tableView 使用 UIImages 渲染缓慢

tableView renders slowly with UIImages

我有一个自定义单元格,用于在应用程序上使用用户 post 填充 tableView。用户可以post发短信或发短信带uiimage

我最初遇到的问题是在包含图像时设置单元格的高度。我最终在 tableview 单元格中得到了高度荒谬的图像,并且图像加载不正确。

所以我将下面的代码添加到 tableView CellforRowAt 函数中,以更改图像的框架,以便以统一的大小加载 UIImage。虽然这现在工作得很好,但当我在 tableview 上滚动时,它超级小故障而且速度很慢。我认为这是因为框架被改变了,处理这个新框架需要一段时间。有没有可能让它更高效更流畅?

  func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
       if indexPath.section == 0 {
        let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
            cell.set(post: posts[indexPath.row])
            cell.delegate = self
            cell.commentDelegate = self
            cell.likeDelegate = self
            cell.selectionStyle = .none
            let imageIndex = posts[indexPath.row].mediaURL
            let url = NSURL(string: imageIndex)! as URL
            if let imageData: NSData = NSData(contentsOf: url) {
               let image = UIImage(data: imageData as Data)
                let newWidth = cell.MediaPhoto.frame.width
                let scale = newWidth/image!.size.width
                let newHeight = image!.size.height * scale
                UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
                image!.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
                    let newImage = UIGraphicsGetImageFromCurrentImageContext()
                    UIGraphicsEndImageContext()
                    cell.MediaPhoto.image = newImage
                cell.MediaPhoto.contentMode = .scaleToFill
                cell.MediaPhoto.clipsToBounds = true
            }
        }
        return cell
        
    }

尝试将工作移到主线程之外。

     class PostTableViewCell: UITableViewCell {

var image: UIImage? {
    didSet {
        setNeedsDisplay()
    }
}
func set(post: Post) {

        DispatchQueue.global().async { [weak self] in
            let strongSelf = self!
            if let url = NSURL(string: strongSelf.mediaUrl) as URL?,
                let imageData: NSData = NSData(contentsOf: url) {
                
                strongSelf.image = UIImage(data: imageData as Data)
               
            
        }
    }
}

override func draw(_ rect: CGRect) {
    guard let image = image else { super.draw(rect) }
    let newWidth = MediaPhoto.frame.width
    let scale = newWidth/image.size.width
    let newHeight = image.size.height * scale
    
    UIGraphicsBeginImageContext(CGSize(width: newWidth, height: newHeight))
    image!.draw(in: CGRect(x: 0, y: 0, width: newWidth, height: newHeight))
   
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    MediaPhoto.image = newImage
    MediaPhoto.contentMode = .scaleToFill
    MediaPhoto.clipsToBounds = true
}

}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell

if indexPath.section == 0 {
    cell.set(post: posts[indexPath.row])
    cell.delegate = self
    cell.commentDelegate = self
    cell.likeDelegate = self
    cell.selectionStyle = .none
}
return cell

}

我最终使用此代码将图像大小固定为 400 x 400,效果很好。它不再呈现缓慢或故障。

func set(post:Posts) {
    
    self.post = post
    
    // get PROFILE image
    let url = post.url
    profileImageView.sd_setImage(with: url, completed: nil)
    
    // get MEDIA image
    let mediaString = post.urlM.absoluteString
    if mediaString == "none" {
        MediaPhoto.image = nil
    } else {
        let mediaUrl = post.urlM
        MediaPhoto.sd_setImage(with: mediaUrl, completed: nil)
        
        //RESIZE MEDIA PHOTO
        let itemSize:CGSize = CGSize(width: 400, height: 400)
        UIGraphicsBeginImageContextWithOptions(itemSize, false, UIScreen.main.scale)
        let imageRect : CGRect = CGRect(x: 0, y: 0, width: itemSize.width, height: itemSize.height)
        MediaPhoto!.image?.draw(in: imageRect)
        MediaPhoto!.image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
    }
}