gpt4 book ai didi

ios - 如何在 TableView 中使用的 UIImageView 扩展中再次从 startAnimation 修复 UIActivityIndi​​catorView

转载 作者:行者123 更新时间:2023-11-29 05:46:25 24 4
gpt4 key购买 nike

我有一个 UIImageView 扩展,其中包含下载设置图像的方法,该扩展还包含一个 UIActivityIndi​​catorView,我在加载图像之前将其设置为 View 图像已加载,我从 UIImageView

中删除或隐藏 UIActivityIndi​​catorView
extension UIImageView {

private static let imageProcessingQueue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".imageprocessing", attributes: .concurrent)

var activityIndicator: UIActivityIndicatorView! {
get {
return objc_getAssociatedObject(self, &activityIndicatorAssociationKey) as? UIActivityIndicatorView
}
set(newValue) {
objc_setAssociatedObject(self, &activityIndicatorAssociationKey, newValue, .OBJC_ASSOCIATION_RETAIN)
}
}

func showActivityIndicatory() {

// activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
activityIndicator = UIActivityIndicatorView(frame: CGRect.init(x: 0, y: 0, width: 50, height: 50))
activityIndicator.center = self.center
activityIndicator.hidesWhenStopped = true
activityIndicator.style = UIActivityIndicatorView.Style.gray

self.isUserInteractionEnabled = false

UIImageView.imageProcessingQueue.async {
DispatchQueue.main.async {
self.activityIndicator.startAnimating()
self.addSubview(self.activityIndicator)

}
}
}

func hideIndicator() {
UIImageView.imageProcessingQueue.async {
DispatchQueue.main.async {
self.activityIndicator.stopAnimating()
self.activityIndicator.removeFromSuperview()

}
}
}

func setImage(url : String) {
self.showActivityIndicatory()
operatorManager.loadImage(url: url) { (image) in
self.image = image
self.hideIndicator()
}
}
}

然后我就可以像这样使用这个扩展函数了,

guard let cell = tableView.dequeueReusableCell(withIdentifier:"Tableview", for: indexPath) as? TableViewCell else {
fatalError()
}

let imagees = list[indexPath.row]

cell.labelView.text = imagees.urlString
cell.iconView.setImage(url: imagees.urlString)

这是从缓存(如果可用)或服务器加载图像的操作

    class LoadImageOperation: ConcurrentOps<UIImage> {

private let session: URLSession
private let url: String
private var task: URLSessionTask?
private var defaultImage: UIImage?
// MARK: - Init

init(session: URLSession = URLSession.shared, url: String) {
self.session = session
self.url = url
self.defaultImage = UIImage(named: "icons")
}


override func main() {

guard let imageURL = URL(string: url) else {
cancel()
return
}



if let cachedImage = DataCache.shared.object(forKey: url) {

DispatchQueue.main.async {
self.complete(result: cachedImage as! UIImage)

}
cancel()
}


task = session.downloadTask(with: imageURL){ (url,response,error) in

guard let url = url ,
let data = try? Data(contentsOf: url),
let image = UIImage(data: data) else {

DispatchQueue.main.async {

if error != nil {
self.complete(result: self.defaultImage!)
} else {
self.complete(result: self.defaultImage!)
}
}
return
}
DispatchQueue.main.async {

DataCache.shared.saveObject(object: image, forKey: self.url)
self.complete(result: image)
}

}
task?.resume()


}

}

操作在这里管理,

func loadImage(url: String, completionHandler: @escaping (_ result: UIImage) ->Void) {

let operation = LoadImageOperation(url: url)

operation.completionHandler = completionHandler
operation.name = "loadImageOperation"
queueManager.enqueue(operation)

}

当我的 tableView 第一次开始加载 indicator 时,它完美地显示和隐藏,但是当我滚动 tableview 时,它开始为 制作动画再次在UIImageView上显示>指示器。我该如何防止这种情况发生?

最佳答案

显示事件指示器的原因是滚动时,单元格会被重用(出于性能原因)来显示新数据。这意味着每次您滚动到新单元格时,它都会加载并调用 cellForRow,同时调用加载事件指示器的函数。

如果您需要一步一步的答案,您应该提供有关如何处理 UITableView 的更多信息,但我认为您可能希望实现图像缓存以避免每次加载单元格时都加载图像。检查this answer了解更多信息。

关于ios - 如何在 TableView 中使用的 UIImageView 扩展中再次从 startAnimation 修复 UIActivityIndi​​catorView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56114459/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com