Прокрутка в табличном представлении происходит с сбоями и медленно

# #swift #firebase #uitableview

Вопрос:

У меня есть код ниже в моей ячейке tableview для загрузки сообщений пользователей в домашнюю ленту. Я изменяю размер изображения, чтобы лучше контролировать размер изображений, отображаемых в приложении. Код работает нормально, и размер изображений хорошо изменен. Однако эта обработка изменения размера значительно замедляет поток сообщений, и прокрутка представления таблицы теперь очень затруднена.

У кого-нибудь есть идеи о том, как переписать это более эффективным способом?

 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 mediaUrl = post.urlM
    MediaPhoto.sd_setImage(with: mediaUrl, completed: nil)
if let imageData: NSData = NSData(contentsOf: mediaUrl) {
       let image = UIImage(data: imageData as Data)
       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
    }
 

Ответ №1:

Не рекомендуется выполнять тяжелые работы в ячейках, такие как рендеринг, форматирование и т. Д.

Я предлагаю использовать kingfisher для загрузки изображений и их отображения.

смотрите больше: Зимородок

Который содержит некоторые полезные функции, такие как:

  • Асинхронная загрузка и кэширование изображений.
  • Предоставляются полезные графические процессоры и фильтры (что вам нужно в данном случае)
  • И так много других функций…

чтобы изменить размер изображений, следуйте приведенным ниже кодам:

 let resizingProcessor = ResizingImageProcessor(referenceSize: CGSize(width: 100.0 , height: 100.0))
let url = URL(string: path)
imageView.kf.indicatorType = .activity
imageView.kf.setImage(with: url,
                      options: [.processor(resizingProcessor)],
                      completionHandler: nil
)
 

для получения дополнительной информации об изменении размера с помощью kingfisher перейдите по ссылке ниже:

Шпаргалка Зимородка

Ответ №2:

Вы должны попробовать использовать NSCache , я обычно создаю файл расширений и создаю этот метод:

 let imageCache = NSCache<AnyObject, AnyObject>()

extension UIImageView {
    
    func loadImageUsingCacheWithUrlString(_ urlString: String) {

        let strUniqueIdentifier_Initial = urlString
        self.accessibilityLabel = strUniqueIdentifier_Initial
        
        if let cachedImage = imageCache.object(forKey: urlString as AnyObject) as? UIImage {
            self.image = cachedImage
            return
        }
        
        guard let url = URL(string: urlString) else { return }
        URLSession.shared.dataTask(with: url, completionHandler: { (data, response, error) in
            
            if error != nil {
                print(error ?? "")
                return
            }
            
            let strUniqueIdentifier_Current = self.accessibilityLabel
            if strUniqueIdentifier_Initial != strUniqueIdentifier_Current {
                return
            }
            
            DispatchQueue.main.async(execute: {
                
                if let downloadedImage = UIImage(data: data!) {
                    imageCache.setObject(downloadedImage, forKey: urlString as AnyObject)
                    
                    self.image = downloadedImage
                }
            })
            
        }).resume()
    }
}
 

А затем вызовите метод следующим образом:

 // I usually use optional values when creating custom objects
if let imgUrl = post?.url {
   imgView.loadImageUsingCacheWithUrlString(imgUrl)
}
 

Лично мне нравится этот вариант, так как я не люблю использовать дополнительные библиотеки.