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

时间:2017-03-19 08:59:27

标签: ios iphone swift asynchronous uiimageview

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

效果很好,所有图像都加载到正确的图像视图中。但这是一个非常缓慢的过程,图像以随机顺序加载。 我很难显示活动指示器并在所有图像完成加载特定单元格时隐藏它,即在加载图像时保持显示指示符并在加载所有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()
    }
}

2 个答案:

答案 0 :(得分:1)

您需要使用DispatchGroup,您可以在进行异步请求时进入和离开。然后使用.notify(queue:)方法,该方法在组为“空”时触发。我能够找到一个代码与您正在寻找的代码非常相似的答案,所以我在这里链接了它: Wait until swift for loop with asynchronous network requests finishes executing

如果您有任何问题,请告诉我。希望这有帮助!

答案 1 :(得分:0)

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

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()