在后台或主线程中执行更新时设置 GIF 图像块 UI

Setting GIF image blockes UI when updating performed in background or main thread

我正在使用 objective-cFLAnimatedImageUIImageView 中设置 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 在完成时显示它)。