美文网首页
iOS开发 - tableView长截图iOS15适配(Swif

iOS开发 - tableView长截图iOS15适配(Swif

作者: 又系黎小明 | 来源:发表于2021-11-03 14:28 被阅读0次

    2021年苹果秋季发布会之后,iOS15的推出,给开发带来了不少的适配问题。(可恶!)

    没办法,那是爸爸。我改咯~😮💨

    先贴上在iOS14及以下版本,正常的长截图完整代码.

    1. 建立一个UITableView的扩展extension
    extension UITableView {
        
        /// 获取最大高度
        /// - Parameters:
        ///   - maxRowCount: 最大row的count
        ///   - maxSectionCount: 最大section的count,为0表示所有
        public func getMaxHeight(with maxRowCount: Int, maxSectionCount: Int = 0) -> CGFloat {
            var sectionCount = maxSectionCount
            if maxSectionCount >= numberOfSections || maxSectionCount <= 0 {
                sectionCount = numberOfSections
            }
            var maxHeight: CGFloat = tableHeaderView?.frame.size.height ?? 0;
            for sectionIndex in 0..<sectionCount {
                var rowCount = numberOfRows(inSection: sectionIndex)
                if (rowCount > maxRowCount) {
                    rowCount = maxRowCount;
                }
                
                maxHeight += delegate?.tableView?(self, heightForHeaderInSection: sectionCount) ?? 0
                for rowIndex in 0..<rowCount {
                    maxHeight += delegate?.tableView?(self, heightForRowAt: IndexPath(row: rowIndex, section: sectionIndex)) ?? 0
                    
                }
            }
            return maxHeight;
        }
        
        /// 获取指定高度的tableView image
        /// - Parameter maxHeight: 最大高度
        public func generateTableViewImage(with maxHeight: CGFloat) -> UIImage? {
            var viewImage: UIImage?
            
            let savedContentOffset = contentOffset
            let savedFrame = frame
            
            let imageHeight = maxHeight > 0 ? maxHeight :contentSize.height
            var screensInTable = 0
            
            if (frame.size.height != 0) {
                screensInTable = Int(ceil(imageHeight / frame.size.height))
            }
            
            let sectionNum = numberOfSections
            
    //        autoreleasepool {
                let imageSize = CGSize(width: frame.size.width, height: maxHeight)
                UIGraphicsBeginImageContextWithOptions(imageSize, false, UIScreen.main.scale)
                
                frame = CGRect(x: 0, y: 0, width: contentSize.width, height: imageHeight)
                
                for i in 0..<screensInTable {
                    let contentOffset = CGPoint(x: CGFloat(0), y: CGFloat(i) * frame.size.height)
                    setContentOffset(contentOffset, animated: false)
                    
                    // 隐藏应该移出屏幕的sectionHeader
                    if (style == .plain) {
                        for i in 0..<sectionNum {
                            let headerRect = rect(forSection: i)
                            if (headerRect.origin.y < contentOffset.y) {
                                setupHeaderView(with: i, true)
                            }
                        }
                    }
                    if let context = UIGraphicsGetCurrentContext() {
                        layer.render(in: context)
                    }
                }
    //        }
           
            viewImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            if (style == .plain) {
                for i in 0..<sectionNum {
                    setupHeaderView(with: i, false)
                }
            }
            
            frame = savedFrame
            setContentOffset(savedContentOffset, animated: false)
            return viewImage
        }
        
        /// 设置HeaderView的显示隐藏
        /// - Parameters:
        ///   - section: header所在的section
        ///   - isHidden: 是否隐藏
        private func setupHeaderView(with section: Int, _ isHidden: Bool) {
            
            var headerView1 = headerView(forSection: section)
            
            if nil == headerView {
                headerView1 = delegate?.tableView?(self, viewForHeaderInSection: section) as? UITableViewHeaderFooterView
            }
            headerView1?.isHidden = isHidden
        }
    }
    
    1. 使用代码. 这里的10,是指最大row的数量。详细代码在extension,就不叙述了。
    guard let image = longShareImageTableView.generateTableViewImage(with: longShareImageTableView.getMaxHeight(with: 10)) else {
    
                    return
                }
    
                shareImage = image
    

    到了iOS15,截图就会缺失了一部分,举个栗子🌰

    WX20211103-140003@2x.png
    很是迷茫,网上好像暂时没有相应的资料和解决办法。后来在https://jishuin.proginn.com/p/763bfbd564b3这篇文章中,找到了灵感之处。
    if #available(iOS 13, *) {
           //iOS 13 系统截屏需要改变tableview 的bounds
           scrollView.layer.bounds = CGRect(x: oldBounds.origin.x, y: oldBounds.origin.y, width: contentSize.width, height: contentSize.height)
       }
       //偏移量归零
       scrollView.contentOffset = CGPoint.zero
       //frame变为contentSize
       scrollView.frame = CGRect(x: 0, y: 0, width: scrollView.contentSize.width, height: scrollView.contentSize.height)
    

    但实测之后发现,把这段结合到自己的截图方法中后,反而会令iOS13版本的截图缺失,iOS15倒是正常了。。。😮

    最后只能把代码变成iOS15之后使用了,最终的代码如下

    /// 获取指定高度的tableView image
        /// - Parameter maxHeight: 最大高度
        public func generateTableViewImage(with maxHeight: CGFloat) -> UIImage? {
            var viewImage: UIImage?
            
            let savedContentOffset = contentOffset
            let savedFrame = frame
            
            let imageHeight = maxHeight > 0 ? maxHeight :contentSize.height
            var screensInTable = 0
            
            if (frame.size.height != 0) {
                screensInTable = Int(ceil(imageHeight / frame.size.height))
            }
            
            let sectionNum = numberOfSections
            
    //        autoreleasepool {
                let imageSize = CGSize(width: frame.size.width, height: maxHeight)
                UIGraphicsBeginImageContextWithOptions(imageSize, false, UIScreen.main.scale)
                
                frame = CGRect(x: 0, y: 0, width: contentSize.width, height: imageHeight)
                
                let oldBounds = layer.bounds
                
            
                if #available(iOS 15, *) {
                    //iOS 15 系统截屏需要改变tableview 的bounds
                    layer.bounds = CGRect(x: oldBounds.origin.x,
                                                     y: oldBounds.origin.y,
                                                     width: contentSize.width,
                                                     height: contentSize.height)
                    
                    //偏移量归零
                    contentOffset = CGPoint.zero
                    //frame变为contentSize
                    frame = CGRect(x: 0, y: 0, width: contentSize.width, height: contentSize.height)
                }
                
                
                for i in 0..<screensInTable {
                    let contentOffset = CGPoint(x: CGFloat(0), y: CGFloat(i) * frame.size.height)
                    setContentOffset(contentOffset, animated: false)
                    
                    // 隐藏应该移出屏幕的sectionHeader
                    if (style == .plain) {
                        for i in 0..<sectionNum {
                            let headerRect = rect(forSection: i)
                            if (headerRect.origin.y < contentOffset.y) {
                                setupHeaderView(with: i, true)
                            }
                        }
                    }
                    if let context = UIGraphicsGetCurrentContext() {
                        layer.render(in: context)
                    }
                }
    //        }
            
            if #available(iOS 15, *) {
                layer.bounds = oldBounds
            }
            
            viewImage = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()
            
            if (style == .plain) {
                for i in 0..<sectionNum {
                    setupHeaderView(with: i, false)
                }
            }
            
            frame = savedFrame
            setContentOffset(savedContentOffset, animated: false)
            return viewImage
        }
    
    WX20211103-135835@2x.png

    打完!收工!
    攰死个人了😂

    相关文章

      网友评论

          本文标题:iOS开发 - tableView长截图iOS15适配(Swif

          本文链接:https://www.haomeiwen.com/subject/zdtczltx.html