美文网首页
swift tableviewcell中imageview自适应

swift tableviewcell中imageview自适应

作者: 松龄学编程 | 来源:发表于2020-05-16 15:43 被阅读0次

    自动布局中,imageview根据图片的宽高自适应高度。需要提前知道图片的宽高,可以服务器返回添加字段。这里提供一种思路,提前使用kingfisher下载所有图片再刷新表,可以解决这个问题。

    private func downloadImages(datas: [SquareModel]) {
            let group = DispatchGroup()
            var heightCache: [String: CGSize] = [:]
            let queue = DispatchQueue(label: "SafeArrayQueue", attributes: .concurrent)
            let downloader = ImageDownloader.default
            let imageUrls = datas.compactMap { (model) -> [String]? in
                return model.pathArrWithoutVideo
            }.flatMap { (urls) -> [String] in
                return urls
            }
            for imageUrl in imageUrls {
                if let url = URL(string: imageUrl) {
                    group.enter()
                    downloader.downloadImage(with: url) { (result) in
                        switch result {
                        case .success(let value):
                            queue.async(group: group, qos: .userInteractive, flags: .barrier) {
                                heightCache[imageUrl] = value.image.size
                                group.leave()
                            }
                        case .failure(_):
                            group.leave()
                        }
                        
                    }
                }
            }
            let videoUrls = datas.filter { (model) -> Bool in
                return model.hasVideo
            }.map { (model) -> String in
                return model.videoCoverUrl
            }
            for videoUrl in videoUrls {
                if let url = URL(string: videoUrl) {
                    group.enter()
                    downloader.downloadImage(with: url) { (result) in
                        switch result {
                        case .success(let value):
                            queue.async(group: group, qos: .userInteractive, flags: .barrier) {
                                heightCache[videoUrl] = value.image.size
                                group.leave()
                            }
                        case .failure(_):
                            group.leave()
                        }
                        
                    }
                }
            }
            group.notify(queue: .main) { [weak self] in
                self?.viewModel.heightCache.merge(heightCache, uniquingKeysWith: { (old, new) -> CGSize in
                    return new
                })
                self?.contentView.tableView.reloadData()
            }
        }
    

    上边的方法,需要依赖图片服务器的速度,如果图片服务器性能不是很好的话,会影响加载速度。这里可以先只是获取图片的size,不做下载。通过url获取图片size,方法如下:

    func getImageSizeWithURL(url: URL)-> CGSize {
            var imageSize: CGSize = .zero
    
            guard let imageSourceRef = CGImageSourceCreateWithURL(url as CFURL, nil)
                else { return imageSize }
            
            guard let imagePropertie = CGImageSourceCopyPropertiesAtIndex(imageSourceRef, 0, nil)  as? Dictionary<String, Any>
                else { return imageSize }
            
            imageSize.width = CGFloat((imagePropertie[kCGImagePropertyPixelWidth as String] as! NSNumber).floatValue)
            imageSize.height = CGFloat((imagePropertie[kCGImagePropertyPixelHeight as String] as! NSNumber).floatValue)
            return imageSize
        }
    

    而且,不需要所有图片的url,都缓存宽高,过滤一下,需要获取宽高的图片。更新下,之前的代码

    func cacheHeight(datas: [SquareModel], completionHandler: @escaping ([SquareModel]) -> Void) {
            let group = DispatchGroup()
            var heightCache: [String: CGSize] = [:]
            let queue = DispatchQueue(label: "SafeArrayQueue", attributes: .concurrent)
            let imageUrls = datas.compactMap { (model) -> [String]? in
                return model.pathArrWithoutAudioVideo
            }.flatMap { (urls) -> [String] in
                return [urls.first ?? ""]
            }
            for imageUrl in imageUrls {
                if let url = URL(string: imageUrl) {
                    group.enter()
                    let size = getImageSizeWithURL(url: url)
                    queue.async(group: group, qos: .userInteractive, flags: .barrier) {
                        heightCache[imageUrl] = size
                        group.leave()
                    }
                }
            }
            let videoUrls = datas.filter { (model) -> Bool in
                return model.hasVideo
            }.map { (model) -> String in
                return model.videoCoverUrl
            }
            for videoUrl in videoUrls {
                if let url = URL(string: videoUrl) {
                    group.enter()
                    let size = getImageSizeWithURL(url: url)
                    queue.async(group: group, qos: .userInteractive, flags: .barrier) {
                        heightCache[videoUrl] = size
                        group.leave()
                    }
                }
            }
            group.notify(queue: .main) { [weak self] in
                self?.viewModel.heightCache.merge(heightCache, uniquingKeysWith: { (old, new) -> CGSize in
                    return new
                })
                completionHandler(datas)
            }
        }
    

    经测试,优化后,速度飞快,很稳定。

    相关文章

      网友评论

          本文标题:swift tableviewcell中imageview自适应

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