Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/43.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 显示活动指示器,直到成功加载所有图像_Ios_Iphone_Swift_Asynchronous_Uiimageview - Fatal编程技术网

Ios 显示活动指示器,直到成功加载所有图像

Ios 显示活动指示器,直到成功加载所有图像,ios,iphone,swift,asynchronous,uiimageview,Ios,Iphone,Swift,Asynchronous,Uiimageview,我有一个collectionView单元,它有五个ImageView。我使用javimuu给出的以下答案在后台加载图像。 它工作正常,所有图像都加载到正确的imageview中。但这是一个非常缓慢的过程和图像加载随机顺序。 当为特定单元格加载所有图像时,我很难显示活动指示器并将其隐藏,即,在加载图像时继续显示指示器,在加载所有5个图像时将其隐藏 请帮忙 更新: func downloadImageFromLink(link:NSURL,group: dispatch_group_t,

我有一个collectionView单元,它有五个ImageView。我使用javimuu给出的以下答案在后台加载图像。

它工作正常,所有图像都加载到正确的imageview中。但这是一个非常缓慢的过程和图像加载随机顺序。 当为特定单元格加载所有图像时,我很难显示活动指示器并将其隐藏,即,在加载图像时继续显示指示器,在加载所有5个图像时将其隐藏

请帮忙

更新:

    func downloadImageFromLink(link:NSURL,group: dispatch_group_t, completion:(isDone: Bool) -> Void) {

    self.image = nil

    imageURL = link.absoluteString
    dispatch_group_enter(group)

    NSURLSession.sharedSession().dataTaskWithURL(link, completionHandler: {
        (data, response, error) -> Void in
        if error != nil {
            print(error)
            return
        }

        if let imageFromCache = imageCache.objectForKey(link.absoluteString) as? UIImage {

            self.image = imageFromCache
            dispatch_group_leave(group)
            return
        }
        dispatch_async(dispatch_get_main_queue(),{

            let imageToCache =  UIImage(data: data!)

            if self.imageURL == link.absoluteString {
                self.image = imageToCache
                imageCache.setObject(imageToCache!, forKey: link.absoluteString)
            }
            dispatch_group_leave(group)
        })
    }).resume()
}

func loadImagesInCell(cell: WatchFaceCell, images:NSArray ,completion:() ->Void) {
    self.startAnimating(cell.contentView)
    let group: dispatch_group_t = dispatch_group_create()
    for model in images{
        if model is WFCreatorModel {
            let wfModel: WFCreatorModel = model as! WFCreatorModel
            switch wfModel.imageType {
            case .Dial:
                cell.dialImage.downloadImageFromLink(wfModel.imageURL,group: group, completion: { (isDone) in
                })
            case .HourHand:
                cell.hourHandImage.downloadImageFromLink(wfModel.imageURL,group: group, completion: { (isDone) in
                })
            case .MinuteHand:
                cell.minuteHandImage.downloadImageFromLink(wfModel.imageURL,group: group, completion: { (isDone) in
                })
            case .SecondHand:
                cell.secondHandImage.downloadImageFromLink(wfModel.imageURL,group: group, completion: { (isDone) in
                })
            case .Notification:
                cell.notificationImage.downloadImageFromLink(wfModel.imageURL, group: group,completion: { (isDone) in
                })
            }//end of switch
        }//end of if else
    }//end of for
    dispatch_group_notify(group, dispatch_get_main_queue()) {
        self.stopAnimating(cell.contentView)
        completion()
    }
}

您需要使用一个
DispatchGroup
,在发出异步请求时可以输入和离开该组。然后使用
.notify(queue:)
方法,该方法在组为“空”时激发。我能够找到一个与您所寻找的代码非常相似的答案,因此我将其链接到此处: .


如果你还有什么问题,请告诉我。希望这有帮助

您应该尝试使用像翠鸟这样的第三方,该第三方拥有执行此类任务所需的所有方法。。下面是一些示例代码,只是为了给你一些东西

var prefetcher: ImagePrefetcher?
var imageItems: [ImageItem]? {
    didSet {
        collectionView.reloadData()
    }
}

// This code goes inside one of your methods
                      self.prefetcher = ImagePrefetcher(urls: urls, optionsInfo: nil, progressBlock: nil, completionHandler: { [weak self]
                            (skippedResources, failedResources, completedResources) -> () in
                            self?.endLoading()
                            self?.imageItems = filteredItems
                            self?.timerLabel.countFrom(15, to: 0, withDuration: 15.0)
                            self?.timerLabel.completionBlock = { self?.startGuessing() }
                        })
        self.prefetcher!.start()

缓慢可能是因为图像太大。要知道什么时候所有的事情都完成了,一个快速的解决方案是保留一个计数器:在调度之前递增它,然后在主队列上的调度中递减它(并检查为零)。@danh你能用一个例子解释一下吗?谢谢你的回答,但这并不能解决我的问题。我怎么知道某个特定单元格的所有5个图像都已加载?您给出的示例仅适用于缓存图像,而不适用于下载图像。我需要分别下载每个图像,以便在正确的单元格中设置正确的图像视图。谢谢您的回复。我尝试过dispatchGroup,它适合我的需要,但我仍然面临一个问题,即活动指示器将很快出现并消失。它点击我维护缓存的调度组离开(组)5次,然后点击调度组通知呼叫。但此时图像不会加载到imageView中。在main_queue()中调用它们会导致UI延迟,这是我最初的问题,因此所有这些代码都没有用。你说此时图像没有加载到imageView中是什么意思?当notify函数运行时,它们没有被加载?我的意思是说,在我从NSURLSession获得结果后,我正在为它们分配一个映像,但是由于它们没有在主线程上运行,因此没有立即分配它们。如果我在主线程上运行它,则UI会滞后。因此,您可以在dispatch_group_notify(group,dispatch_get_main_queue())中将图像一次性分配给它们的ImageView{我会尝试一下,并让您知道。谢谢!