问题
In my app I'm using UICollectionView
and I've decided to use it as in the code below:
class UserList: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {
@IBOutlet weak var tview: UICollectionView!
let reuseIdentifier = "cell"
var items = NSMutableArray()
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = tview.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! MyCollectionViewCell
let user:SingleUser = self.items[indexPath.item] as! SingleUser
cell.username.text = user.name
if let checkedUrl = NSURL(string: user.photo) {
cell.userImg.contentMode = .ScaleAspectFit
getDataFromUrl(checkedUrl) { (data, response, error) in
dispatch_async(dispatch_get_main_queue()) { () -> Void in
guard let data = data where error == nil else { return }
print(response?.suggestedFilename ?? "")
cell.userImg.image = UIImage(data: data)
}
}
}
return cell
}
So I have a cell with a UILabel
and UIImage
and for each object fetched from json I parse it and I assign user's data to that cell.
When I load the window I see usernames with photos of them, but when I start scrolling through the collection view the photos of users change and users get different photos than they should have.
I've read it might be something related to cell reusing (so far I know nothing about it), I just assumed it should be loaded once (when user opens this panel) and then left as it is. However it seems like this data is "fetched" each time user scrolls that list.
So how can I exactly fix my problem and be sure each time user scrolls the list - the data will be correct?
One more thing that might be useful here - method getDataFromUrl
that fetches photos from urls:
func getDataFromUrl(url:NSURL, completion: ((data: NSData?, response: NSURLResponse?, error: NSError? ) -> Void)) {
NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
completion(data: data, response: response, error: error)
}.resume()
}
回答1:
What Eugene said is correct, but if you don't want to change the code you have already too much. You can add an optional UIImage property on SingleUser, call it "image," then you can say something like:
if user.image == nil{
getDataFromUrl(checkedUrl) { (data, response, error) in
dispatch_async(dispatch_get_main_queue()) { () -> Void in
guard let data = data where error == nil else { return }
print(response?.suggestedFilename ?? "")
let image = UIImage(data: data)
user.image = image
//Check if this cell still has the same indexPath, else it has been dequeued, and image shouldn't be updated
if collectionView.indexPathForCell(cell) == indexPath
{
cell.userImg.image = image
}
}
}
}else{
cell.userImg.image = user.image!
}
}
来源:https://stackoverflow.com/questions/36510137/strange-behavior-when-user-scrolls-the-list-of-uiviewcollectioncells-in-my-app