在后台或主线程中执行更新时设置 GIF 图像块 UI
Setting GIF image blockes UI when updating performed in background or main thread
我正在使用 objective-c
库 FLAnimatedImage 在 UIImageView
中设置 GIF 图像。我目前面临的问题是 UI 在加载 GIF 图像时被阻止(触摸未在显示在前面的叠加层 UIView
上注册图像的重叠视图是 hidden/shown 点击 )。我尝试在后台线程和主线程上更新图像,结果保持不变。我在这里做错了什么吗?或者任何替代方案? (PS。我还有一个带有检测链接的 UITextView
,怀疑这是否重要)
UITableViewCell
//Main Thread blocks UI
dispatch_async(dispatch_get_main_queue(), { () -> Void in
cell.shotImg.setShotImage(self.shots[self.currentIndex])
})
//Background thread also blocks ui. See code below for background thread function
backgroundThread(0.1, completion: {
cell.shotImg.setShotImage(self.shots[self.currentIndex])
})
FLAnimatedImage 扩展
extension FLAnimatedImageView{
func setRegularImage(url: String){
self.af_setImageWithURL(NSURL(string: url)!)
}
func setGIFImage(url: String){
let animatedImage = FLAnimatedImage(animatedGIFData: NSData(contentsOfURL: NSURL(string: url)!)!)
self.animatedImage = animatedImage
}
func setShotImage(shot: Shots){
var url: String!
if(shot.images.hidpi != nil){
url = shot.images.hidpi
}else{
url = shot.images.normal
}
if(shot.animated!){
self.setGIFImage(url)
}else{
self.setRegularImage(shot.images.normal)
}
}
}
后台线程
func backgroundThread(delay: Double = 0.0, background: (() -> Void)? = nil, completion: (() -> Void)? = nil) {
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0)) {
if(background != nil){ background!(); }
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
dispatch_after(popTime, dispatch_get_main_queue()) {
if(completion != nil){ completion!(); }
}
}
}
我的猜测是问题是这样的:
NSData(contentsOfURL: NSURL(string: url))
这不是您下载内容的方式(如果您正在这样做的话)。使用 NSURLSession.
除非你有静态单元格,否则你不能直接在后台线程中更新单元格。当您滚动时,table 视图将为新出现的单元格重用屏幕外的单元格。当后台任务完成时,该单元格可能属于另一行。
相反,您应该在任务完成时将图像存储在数组中,然后调用 reloadData(在主线程上)。然后 cellForRowAtIndexPath 应该显示数组中的图像,或者如果尚未获取它,则在后台获取它(这将触发 reloadData 在完成时显示它)。
我正在使用 objective-c
库 FLAnimatedImage 在 UIImageView
中设置 GIF 图像。我目前面临的问题是 UI 在加载 GIF 图像时被阻止(触摸未在显示在前面的叠加层 UIView
上注册图像的重叠视图是 hidden/shown 点击 )。我尝试在后台线程和主线程上更新图像,结果保持不变。我在这里做错了什么吗?或者任何替代方案? (PS。我还有一个带有检测链接的 UITextView
,怀疑这是否重要)
UITableViewCell
//Main Thread blocks UI
dispatch_async(dispatch_get_main_queue(), { () -> Void in
cell.shotImg.setShotImage(self.shots[self.currentIndex])
})
//Background thread also blocks ui. See code below for background thread function
backgroundThread(0.1, completion: {
cell.shotImg.setShotImage(self.shots[self.currentIndex])
})
FLAnimatedImage 扩展
extension FLAnimatedImageView{
func setRegularImage(url: String){
self.af_setImageWithURL(NSURL(string: url)!)
}
func setGIFImage(url: String){
let animatedImage = FLAnimatedImage(animatedGIFData: NSData(contentsOfURL: NSURL(string: url)!)!)
self.animatedImage = animatedImage
}
func setShotImage(shot: Shots){
var url: String!
if(shot.images.hidpi != nil){
url = shot.images.hidpi
}else{
url = shot.images.normal
}
if(shot.animated!){
self.setGIFImage(url)
}else{
self.setRegularImage(shot.images.normal)
}
}
}
后台线程
func backgroundThread(delay: Double = 0.0, background: (() -> Void)? = nil, completion: (() -> Void)? = nil) {
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_USER_INITIATED.rawValue), 0)) {
if(background != nil){ background!(); }
let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
dispatch_after(popTime, dispatch_get_main_queue()) {
if(completion != nil){ completion!(); }
}
}
}
我的猜测是问题是这样的:
NSData(contentsOfURL: NSURL(string: url))
这不是您下载内容的方式(如果您正在这样做的话)。使用 NSURLSession.
除非你有静态单元格,否则你不能直接在后台线程中更新单元格。当您滚动时,table 视图将为新出现的单元格重用屏幕外的单元格。当后台任务完成时,该单元格可能属于另一行。
相反,您应该在任务完成时将图像存储在数组中,然后调用 reloadData(在主线程上)。然后 cellForRowAtIndexPath 应该显示数组中的图像,或者如果尚未获取它,则在后台获取它(这将触发 reloadData 在完成时显示它)。