如何仅在查询回调后加载视图
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];
}
我有一个照片集合视图作为另一个视图的子视图。我只想在执行查询以获取图片来填充它之后才显示它,如果还没有准备好,则放置一个 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];
}