[英]Asynchronously Loading Image constantly causes image to flicker?
I have a header view for every UITableViewCell
. 我为每个
UITableViewCell
都有一个标题视图。 In this header view, I load a picture of an individual via an asynchronous function in the Facebook API. 在此标头视图中,我通过Facebook API中的异步函数加载个人的图片。 However, because the function is asynchronous, I believe the function is called multiple times over and over again, causing the image to flicker constantly.
但是,由于该函数是异步的,因此我相信该函数会被多次调用,从而导致图像不断闪烁。 I would imagine a fix to this issue would be to load the images in
viewDidLoad
in an array first, then display the array contents in the header view of the UITableViewCell
. 我想解决此问题的方法是先将图像加载到
viewDidLoad
中的数组中,然后在UITableViewCell
的标题视图中显示数组的内容。 However, I am having trouble implementing this because of the asynchronous nature of the function: I can't seem to grab every photo, and then continue on with my program. 但是,由于该函数的异步特性,我在实现它时遇到了麻烦:我似乎无法抓住每张照片,然后继续执行我的程序。 Here is my attempt:
这是我的尝试:
//Function to get a user's profile picture
func getProfilePicture(completion: (result: Bool, image: UIImage?) -> Void){
// Get user profile pic
let url = NSURL(string: "https://graph.facebook.com/1234567890/picture?type=large")
let urlRequest = NSURLRequest(URL: url!)
//Asynchronous request to display image
NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue()) { (response:NSURLResponse!, data:NSData!, error:NSError!) -> Void in
if error != nil{
println("Error: \(error)")
}
// Display the image
let image = UIImage(data: data)
if(image != nil){
completion(result: true, image: image)
}
}
}
override func viewDidLoad() {
self.getProfilePicture { (result, image) -> Void in
if(result == true){
println("Loading Photo")
self.creatorImages.append(image!)
}
else{
println("False")
}
}
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
//Show section header cell with image
var cellIdentifier = "SectionHeaderCell"
var headerView = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! SectionHeaderCell
headerView.headerImage.image = self.creatorImages[section]
headerView.headerImage.clipsToBounds = true
headerView.headerImage.layer.cornerRadius = headerView.headerImage.frame.size.width / 2
return headerView
}
As seen by the program above, I the global array that I created called self.creatorImages
which holds the array of images I grab from the Facebook API is always empty and I need to "wait" for all the pictures to populate the array before actually using it. 如上面的程序所示,我创建的名为
self.creatorImages
的全局数组保存着从Facebook API抓取的图像数组,始终为空,我需要“等待”所有图片,然后才能实际填充该数组使用它。 I'm not sure how to accomplish this because I did try a completion handler in my getProfilePicture
function but that didn't seem to help and that is one way I have learned to deal with asynchronous functions. 我不确定如何完成此操作,因为我确实在
getProfilePicture
函数中尝试了完成处理程序,但这似乎无济于事,这是我学会处理异步函数的一种方法。 Any other ideas? 还有其他想法吗? Thanks!
谢谢!
I had the same problem but mine was in Objective-C Well, the structure is not that different, what i did was adding condition with: headerView.headerImage.image 我遇到了同样的问题,但是我的问题在Objective-C中,结构没什么不同,我所做的只是添加条件: headerView.headerImage.image
Here's an improved solution that i think suits your implementation.. since you placed self.getProfilePicture
inside viewDidLoad
it will only be called once section
==0 will only contain an image, 这是一个改进的解决方案,我认为适合您的实现。.由于您将
self.getProfilePicture
放置在viewDidLoad
,因此只有在section
== 0时仅包含图像,它才会被调用,
the code below will request for addition image if self.creatorImages
's index is out of range/bounds 如果
self.creatorImages
的索引超出范围/界限,则下面的代码将请求添加图像
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
//Show section header cell with image
var cellIdentifier = "SectionHeaderCell"
var headerView = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! SectionHeaderCell
if (section < self.creatorImages.count) // validate self.creatorImages index to prevent 'Array index out of range' error
{
if (headerView.headerImage.image == nil) // prevents the blinks
{
headerView.headerImage.image = self.creatorImages[section];
}
}
else // requests for additional image at section
{
// this will be called more than expected because of tableView.reloadData()
println("Loading Photo")
self.getProfilePicture { (result, image) -> Void in
if(result == true) {
//simply appending will do the work but i suggest something like:
if (self.creatorImages.count <= section)
{
self.creatorImages.append(image!)
tableView.reloadData()
println("self.creatorImages.count \(self.creatorImages.count)")
}
//that will prevent appending excessively to data source
}
else{
println("Error loading image")
}
}
}
headerView.headerImage.clipsToBounds = true
headerView.headerImage.layer.cornerRadius = headerView.headerImage.frame.size.width / 2
return headerView
}
You sure have different implementation from what i have in mind, but codes in edit history is not in vain, right?.. hahahaha.. ;) Hope i've helped you.. Cheers! 您确定的实现方式与我的想法有所不同,但是编辑历史记录中的代码没有白费,对吧?..哈哈哈哈..;)希望我对您有所帮助..干杯!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.