如何仅在查询回调后加载视图

How to load view only after query callback

我有一个照片集合视图作为另一个视图的子视图。我只想在执行查询以获取图片来填充它之后才显示它,如果还没有准备好,则放置一个 activity 指示符。 我试图将我的代码放在 viewWillAppear 中,但在显示视图之前我没有下载照片。处理此问题的最佳方法是什么?

override func viewWillAppear(animated: Bool) {

    super.viewWillAppear(animated)

    let query = queryAPI()
    query.userExtra(currentUser, completion: { (user:ModelUser) -> () in

        self.currentUser = user

        if let userPhotos = self.currentUser.photos as [ModelAttachment]! {

            self.photos = [UIImage]()

            for object in userPhotos as [ModelAttachment] {

                Utils.getImageAsync(object.url!, completion: { (img: UIImage?) -> () in

                    self.photos?.append(img!)
                    object.image = img

                })

            }

            self.photosCollectionView.reloadData()

        }

    })


}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    if collectionView == photosCollectionView {

        if let hasPhotos = photos as [UIImage]! {

            return photos!.count

        } else {

            return 0
        }

    }else{
        return friends.count
    }
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    if collectionView == photosCollectionView {
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! UICollectionViewCell

        let imageView = cell.viewWithTag(1) as! UIImageView
        let photo = photos![indexPath.row]
        imageView.image = photo
        return cell

    }
}

以及异步获取图像的函数:

class func getImageAsync(url:String, completion: (UIImage?) -> ()){
    var escapedUrl = url.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
    var imageUrl = NSURL(string: escapedUrl!)

    if(imageUrl == nil)
    {
        println("Invalid Url!")
        completion(nil)
    }
    else
    {
        var stdUrl = imageUrl!.standardizedURL!
        println("Downlading image: "+stdUrl.description)
        let req = NSURLRequest(URL: stdUrl)
        NSURLConnection.sendAsynchronousRequest(req, queue: NSOperationQueue.mainQueue()) { (resp, data, error) -> Void in
            var image: UIImage?
            if data != nil {
                image = UIImage(data: data!)!
            } else {
                println("Error while download the image: \(error)")

            }

            dispatch_async(dispatch_get_main_queue()) {
                completion(image)
            }

        }
    }

}

针对您的评论,"The function is in another file as I am using it in different places in my code, how can I call reload the data of another controller there?"

有多种方法可以做到这一点。一种方法是 post 一个 NSNotification 并在你的视图控制器上添加一个观察者。

给post一个通知:

[[NSNotificationCenter defaultCenter] 
        postNotificationName:@"TestNotification" 
        object:self];

接收和回复通知:

- (void) viewDidLoad {
    [[NSNotificationCenter defaultCenter] addObserver:self
            selector:@selector(receiveTestNotification:) 
            name:@"TestNotification"
            object:nil];
}

- (void) receiveTestNotification:(NSNotification *) notification
{
    if ([[notification name] isEqualToString:@"TestNotification"])
        [self.photosCollectionView reloadData];
}