UITableViewCell Image gets Larger when selected - ios

I'm working on an app that includes some functionality that shows a list of photo albums. I'm using a vanilla UITableView and vanilla UITableViewCells. I'm using a Subtitle Style UITableViewCell and setting a thumbnail image on cell.imageView.image. Note: This is not a custom cell, it's the built-in cell imageView.
The problem is that when I tap a cell, the imageView gets LARGER, which then looks weird, because a) that's not intuitive behavior and b) it no longer matches up with every other row.
Before the selection, the cell's imageView frame is:
cell.imageView.frame: {{16, 1}, {84, 84}}
After the selection, the cells' imageView frame is:
cell.imageView.frame: {{16, 0}, {88, 87.5}}
I don't have any code involved, this is a vanilla UITableViewCell.
The only code I have that interacts with the imageView is the PhotoKit code which I use to fetch the photo asset and update the cell:
PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
options.resizeMode = PHImageRequestOptionsResizeModeExact;
[self.imageManager requestImageForAsset:asset
targetSize:AssetGridThumbnailSize
contentMode:PHImageContentModeAspectFill
options:options
resultHandler:^(UIImage *result, NSDictionary *info) {
// Only update the thumbnail if the cell tag hasn't changed.
// Otherwise, the cell has been re-used.
if (cell.tag == currentTag) {
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
cell.imageView.image = result;
}
}];
Why is this happening? How can I stop it?

your custom UITableViewCell have a outlet with name "imageView" which cause the problem. remove that outlet and the problem is fixed

i find when you set the UIImageView.ContentMode = UIViewContentModeScaleAspectFill
if you request a web image ,and download has finish and callback,the imageview will be change it's frame
you can try this method
[img setClipsToBounds:YES];

Related

How would I get my image to occupy the whole image view?

I have an image view with constraints set up, and the image that I load in (from a URL) doesn't fill the whole image view for some reason. I included a picture of the one in question followed by the detail view of the same 'post'. The same code is used for both. In the detail view (one that appears correctly), I set the post image in during viewdidload, and it's a standalone view. The one that loads in wonky is a table view cell with a custom class, and the image is set in the cellForRowAtIndexPath. I do resize the image before I send it to Back4App with parse to 500x500, and the image views are both set to clip to bounds and aspect fit. the uiimageview constraints are exactly the same, with horizontal alignment of zero, a fixed width and height, and constraints for all four sides (8 away from nearest neighbors)
here are code snippets for how both of them are done:
pink background:
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
PostCell *cell = [self.tableView dequeueReusableCellWithIdentifier:#"PostCell"];
Post *post = self.posts[indexPath.row];
PFUser *user = post.author;
[user fetchInBackgroundWithBlock:^(PFObject * _Nullable object, NSError * _Nullable error) {
cell.usernameLabel.text = post.author.username;
}];
cell.titleLabel.text = post.caption;
cell.isLiked = NO;
NSURL *imageURL = [NSURL URLWithString:post.image.url];
[cell.imageView setImageWithURL:imageURL];
return cell;
}
one that loads correctly:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
PFUser *user = self.post.author;
[user fetchInBackgroundWithBlock:^(PFObject * _Nullable object, NSError * _Nullable error) {
self.usernameTextLabel.text = self.post.author.username;
}];
self.titleTextLabel.text = self.post.caption;
self.descriptionTextLabel.text = self.post.bodyText;
NSURL *postImageURL = [NSURL URLWithString:self.post.image.url];
[self.postImageView setImageWithURL:postImageURL];'''
}
Any tips? There may be some basics that I don't have a handle on - i took a crash course basically and I've only been at this for about 3 weeks so I don't understand a lot of this as deeply as I wish I did.
I've set the background color to pink so you could see the image size vs image view
one that loads correctly
side note: i literally can't figure out how to do blocks of code correctly??? i'm following what it says lol
Check following points
Debug the frame size of the ImageView that it is correct which you supplied.
Set following to the ImageView
[cell.imageView setImageWithURL:imageURL];
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
[cell.imageView setClipsToBounds:YES];
I was accidentally using the default imageView that the cell comes with instead of my own outlet to my new image view.

How to auto-layout the UIImageview base on its image size after downloading the image via SDWebImage

I built a sample project hosted on GitHub.
There is a table view and its custom cell has a multiple line UILabel and a dynamic image view base on its image size. I built it step by step to verify the auto-layout issue on the custom cell.
In the 3rd sample table view (Table3ViewController) which has the above view structure, I tested it with sample random length text and local images. It succeeds, just like Apple documentation and this thread said.
Actually, all the auto-layout tutorials or examples from google search results are tested base on the local image assets, no SDWebImage usage related, basically.
In Table4ViewController, the UIImageView/UITableViewCell(CustomCell) finished its subview's layout before the SDWebImage set the final image object to UIImageView asynchronously.
Here is my question, how to re-layout the UITableViewCell(CustomCell) after the SDWebImage downloaded the image from the network?
Here are my constraints within CustomCell.
[label mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.contentView.top);
make.centerX.width.equalTo(self.contentView);
make.bottom.equalTo(imageView.top);
make.height.greaterThanOrEqualTo(#16);
}];
[imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(label.bottom);
make.bottom.equalTo(self.contentView.bottom);
make.centerX.width.equalTo(self.contentView);
make.height.lessThanOrEqualTo(#200);
}];
I tried to move the implementation to initWithStyle:reuseIdentifier: or updateConstraints or layoutSubviews method, all the results are the same and failed.
Here is the image view assignment within cellForRow without placeholder image.
__weak __typeof(cell) weakCell = cell;
[cell.theImageView sd_setImageWithURL:[NSURL URLWithString:dict.allValues.firstObject]
completed:^(UIImage *_Nullable image, NSError *_Nullable error, SDImageCacheType cacheType, NSURL *_Nullable imageURL) {
__strong __typeof(cell) strongCell = weakCell;
[strongCell setNeedsUpdateConstraints];
[strongCell updateConstraintsIfNeeded];
}];
Assume a network image has size 400x400 points, there is no reserved placeholder image in cell, the update constraint and layout subviews' request will be ready and finished asynchronously successfully. However, the new cell's height won't be recalculated into the contentSize of tableview, the draw process of CustomCell won't be called. It fails.
Here is the image view assignment within cellForRow with placeholder image.
__weak __typeof(cell) weakCell = cell;
[cell.theImageView sd_setImageWithURL:[NSURL URLWithString:dict.allValues.firstObject]
placeholderImage:GetImageWithColor(DarkRandomColor, CGRectGetWidth(tableView.frame), 400)
completed:^(UIImage *_Nullable image, NSError *_Nullable error, SDImageCacheType cacheType, NSURL *_Nullable imageURL) {
__strong __typeof(cell) strongCell = weakCell;
[strongCell setNeedsUpdateConstraints];
[strongCell updateConstraintsIfNeeded];
}];
The final image will be drawn with the same size of reserved placeholder image finally, but I expected the final image's size even specified ratio.
So, how to re-layout the image view's size constraint after downloading the image asynchronously?

UITableView scrolling is not smooth

I have the smooth scrolling issue at my UITableView with UITableViewCell which contains UIImageView. Similar issues could be found all over the StrackOverflow but none of the proposed solutions helped me to completely get rid of the lag.
My case is quite common:
images are stored at application storage (in my sample at app bundle)
images could have different size (500x500, 1000x1000, 1500x1500)
I need to display those images in UITableView where UIImageView size is 120x120 (retina)
I have followed multiple optimization tips and managed to optimize scrolling a lot.
Unfortunately it is still not perfect. This is my scenario:
first I moved all the image loading/processing/resizing logic to the background thread
UITableViewCell reuse is enabled
once UITableViewCell is in view I clear old values (settings to null) and start background thread to load the image
at this point we are in background thread and I'm adding 500 ms delay to avoid settings new image to often (in case we are scrolling fast) (see below explanation)
if UIImage exists at static image cache (regular dictionary with UIImage instances) - fetch that one and go to the step 9.
if not - load new image from bundle (imageWithName) using url to app bundle (in real world scenario images will be stored to application storage, not bundle)
once image is loaded resize it to 120x120 using graphics context
save resized image to the static image cache
at this point we have instance to UIImage and process is in the background thread. From here we move back to UI Thread with the given image
if data context was cleared (for example UITableViewCell disappeared or was reused to display another image) we skip processing of the currently available image.
if data context is the same - assign UIImage to UIImageView with an alpha animation (UIView.Animate)
once UITableViewCell is out of view - clear the data context
Originally before starting new background thread to fetch the image here (step 1) was UIImage cache check without background thread. In this case if we have the image in the cache we assign it instantly and this introduces a great lag during fast scrolling (we assign images to often as long as we fetch them instantly). Those lines are commented at my example attached below.
There are still two issues:
at some point during scrolling I still have a small lag (at the
moment when I'm assign new UIImage to UIImageView.
(this one is more noticeable) when you tap on item and go back from details there is a lag right before back navigation animation is finished.
Any suggest how to deal with those two issues or how to optimize my scenario are appreciated
Please take into account that sample written in Xamarin but I don't believe that Xamarin is the cause of the problem as long as I have the same issue for the app written in ObjectiveC as well.
Smooth Scrolling Test App
Did you every tried to populate your TableView with only one 120x120 Image which is saved in your Bundle? This way you can check, if the problem occurs of your Image rendering
Instead of resizing all your images to 120x120 and save them in cache, I would recommend creating and using a thumbnail of all your images. You are somehow already doing this, but you are doing this couple of times (everytime you are scrolling or if your cache is full).
In our last project we had a UICollectionView with book covers. Most of the covers were between 400-800kb big and the feeling while scrolling was really bad. So we created a thumbnail for each image (thumbails about 40-50kb) and used the thumbnails instead of real covers. Works like a charm! I attached the thumbnail creation function
- (BOOL) createThumbnailForImageAtFilePath:(NSString *)sourcePath withName:(NSString *)name {
UIImage* sourceImage = [UIImage imageWithContentsOfFile:sourcePath];
if (!sourceImage) {
//...
return NO;
}
CGSize thumbnailSize = CGSizeMake(128,198);
float imgAspectRatio = sourceImage.size.height / sourceImage.size.width;
float thumbnailAspectRatio = thumbnailSize.height/thumbnailSize.width;
CGSize scaledSize = thumbnailSize;
if(imgAspectRatio >= thumbnailAspectRatio){
//image is higher than thumbnail
scaledSize.width = scaledSize.height * thumbnailSize.width / thumbnailSize.height;
}
else{
//image is broader than thumbnail
scaledSize.height = scaledSize.width * imgAspectRatio;
}
UIGraphicsBeginImageContextWithOptions( scaledSize, NO, 0.0 );
CGRect scaledImageRect = CGRectMake( 0.0, 0.0, scaledSize.width, scaledSize.height );
[sourceImage drawInRect:scaledImageRect];
UIImage* destImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSString* thumbnailFilePath = [[self SOMEDIRECTORY] stringByAppendingPathComponent:name];
BOOL success = [UIImageJPEGRepresentation(destImage, 0.9) writeToFile:thumbnailFilePath atomically:NO];
return success;
}
Try facebook's Async Display library.
https://github.com/facebook/AsyncDisplayKit
Really easy to use.. from their guide: http://asyncdisplaykit.org/guide/
_imageNode = [[ASImageNode alloc] init];
_imageNode.backgroundColor = [UIColor lightGrayColor];
_imageNode.image = [UIImage imageNamed:#"hello"];
_imageNode.frame = CGRectMake(10.0f, 10.0f, 40.0f, 40.0f);
[self.view addSubview:_imageNode.view];
This decodes the image on a background thread.
I'm not sure if it's easy to use iOS libraries on Xamarin but if it's easy, give this a shot.
I sub-class Paul Hegarty's CoreDataTableViewController and employ thumbnails of my photos in the CoreDataTableView.
Look for the examples in Lecture 14 titled FlickrFetcher and Photomania. You will also need to download the CoreDataTableViewController at that same link.
Make a CoreData Entity with an appropriate title and define whatever attributes (data variables) you want. You will need to define two "Transformable" attributes, one for the photo and one for the thumbnail.
Then load your thumbnail in the CoreDataTableView:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *exceptions = [NSArray arrayWithObjects:#"SCR", #"DNS", #"NT", #"ND", #"NH", nil];
static NSString *CellIdentifier = #"resultsDisplayCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
MarksFromMeets *athleteMarks = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString* date = [ITrackHelperMethods dateToAbbreviatedString:athleteMarks.meetDate];
NSMutableString *title = [NSMutableString stringWithFormat:#"%#", athleteMarks.markInEvent];
NSMutableString *subTitle = [NSMutableString stringWithFormat:#"%# - %#",date, athleteMarks.meetName];
[title replaceOccurrencesOfString:#"(null)"
withString:#""
options:0
range:NSMakeRange(0, [title length])];
// cell.imageView.image = athleteMarks.photoThumbNail; // Don't like image in front of record.
[cell.textLabel setFont:[UIFont
fontWithName:#"Helvetica Neue" size:18]];
[cell.detailTextLabel setFont:[UIFont fontWithName:#"Helvetica Neue" size:16]];
[cell.detailTextLabel setTextColor:[UIColor grayColor]];
// make selected items orange
if ([athleteMarks.eventPR integerValue] != 0
&& (![exceptions containsObject:athleteMarks.markInEvent])) {
title = [NSMutableString stringWithFormat:#"%# (PR)",title];
[cell.textLabel setTextColor:[UIColor redColor]];
}
else if ([athleteMarks.eventSB integerValue] != 0
&& (![exceptions containsObject:athleteMarks.markInEvent])) {
title = [NSMutableString stringWithFormat:#"%# (SB)",title];
[cell.textLabel setTextColor:[UIColor orangeColor]];
} else {
[cell.textLabel setTextColor:[UIColor grayColor]];
}
cell.textLabel.text = title;
cell.detailTextLabel.text = subTitle;
cell.indentationLevel = indentationLevelOne;
cell.indentationWidth = indentationForCell;
return cell;
}
If you want, I can send you an example of a Category for an Entity's NSManagedObject Sub-Class. This Category loads the photo and the thumbnail into CoreData Entity. The first time will be slow. However, after that the user should be able to scroll through TableView smoothly and then all the updated results will load automatically. Let me know.
One nice thing is that CoreData handles all the memory management.
Good luck!
I don't have enough rep to comment, So here's an answer which helped my tableview scrolling performance:
Make the tableview height larger than the viewable window. Cells will load "off screen" and helps improve scroll smoothness.
Do your image processing in the following method:
-(void)tableView:(UITableView *)tableView
willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
Those two tricks got my table flowing really nice. I'm getting my image data from an API service and AFNETWORKING has an awesome image loader, but not necessary for you since images are in the bundle.
Maybe you could try SDWebImage instead. It is also a xamarin component
which fashions an asynchronous image downloader and asynchronous memory and disk image caching with automatic cache expiration handling. Using it would probably mean throwing away a lot of hard written code, but it might be worth it -plus your code will become a lot simpler. In iOS you can also setup a SDWebImageManager inside the viewDidLoad of a controller:
- (void)viewDidLoad{
...
SDWebImageManager *manager = [SDWebImageManager sharedManager];
manager.delegate = self;
...
}
and set the view controller as the delegate. Then, when the following delegate method is called:
- (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL
you could scale your images to thumbs of the appropriate size before caching them.
Hope that helps.
Weel I had a similar problem, my scroll was not smooth. I am inserting in the table a variable UIImageView with inside labelViews.
What I did was to change the method HeightforRowAtIndexPath for estimatedHeightforRowAtIndexPath and now scroll is smooth.

UITableView with images crashes app when I scroll down a lot

I have this simple UITableView and each cell has an image corresponding to it. All I'm doing is displaying a title for the image and the image itself in each cell. Here is my cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// this is where the data for each cell is
NSDictionary *dataForThisCell = cachedData.posts[indexPath.row][#"data"];
// this creates a new cell or grabs a recycled one, I put NSLogs in the if statement to make sure they are being recycled, they are.
post *cell = (post *) [self.tableView dequeueReusableCellWithIdentifier:#"postWithImage"];
if (cell == nil) {
cell = [[[NSBundle mainBundle]loadNibNamed:#"postWithImage" owner:self options:nil]objectAtIndex:0];
[cell styleCell];
}
// if this cell has an image we need to stick it in the cell
NSString *lowerCaseURL = [dataForThisCell[#"url"] lowercaseString];
if([lowerCaseURL hasSuffix: #"gif"] || [lowerCaseURL hasSuffix: #"bmp"] || [lowerCaseURL hasSuffix: #"jpg"] || [lowerCaseURL hasSuffix: #"png"] || [lowerCaseURL hasSuffix: #"jpeg"]) {
// if this cell doesnt have an UIImageView, add one to it. Cells are recycled so this only runs several times
if(cell.preview == nil) {
cell.preview = [[UIImageView alloc] init];
[cell.contentView addSubview: cell.preview];
}
// self.images is an NSMutableDictionary that stores the width and height of images corresponding to cells.
// if we dont know the width and height for this cell's image yet then we need to know now to store it
// once the image downloads, and then cause our table to reload so that heightForRowAtIndexPath
// resizes this cell correctly
Boolean shouldReloadData = self.images[dataForThisCell[#"name"]] == nil ? YES : NO;
// download image
[cell.preview cancelImageRequestOperation];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString: dataForThisCell[#"url"]]];
[request addValue:#"image/*" forHTTPHeaderField:#"Accept"];
[cell.preview setImageWithURLRequest: request
placeholderImage: [UIImage imageNamed:#"thumbnailLoading.png"]
success: ^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
// if we indicated earlier that we didnt know the dimensions of this image until
// just now after its been downloaded, then store the image dimensions in self.images
// and tell the table to reload so that heightForRowAtIndexPath
// resizes this cell correctly
if(shouldReloadData) {
NSInteger imageWidth = image.size.width;
NSInteger imageHeight = image.size.height;
if(imageWidth > [ColumnController columnWidth]) {
float ratio = [ColumnController columnWidth] / imageWidth;
imageWidth = ratio * imageWidth;
imageHeight = ratio* imageHeight;
}
if(imageHeight > 1024) {
float ratio = 1024 / imageHeight;
imageHeight = ratio * imageHeight;
imageWidth = ratio* imageWidth;
}
self.images[dataForThisCell[#"name"]] = #{ #"width": #(imageWidth), #"height": #(imageHeight), #"titleHeight": #([post heightOfGivenText: dataForThisCell[#"title"]]) };
[self.tableView reloadData];
// otherwise we alreaady knew the dimensions of this image so we can assume
// that heightForRowAtIndexPath has already calculated the correct height
// for this cell
}else{
// assign the image we downloaded to the UIImageView within the cell
cell.preview.image = image;
// position the image
NSInteger width = [self.images[dataForThisCell[#"name"]][#"width"] integerValue];
NSInteger height = [self.images[dataForThisCell[#"name"]][#"height"] integerValue];
cell.preview.frame = CGRectMake( ([ColumnController columnWidth] - width)/2 , [self.images[dataForThisCell[#"name"]][#"titleHeight"] integerValue] + 10, width, height);
}
}
failure: ^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {}];
}
// set title of the cell
cell.title.text = [NSString stringWithFormat: #"%#\n\n\n\n\n", dataForThisCell[#"title"]];
`enter code here`// ask for a restyle
[cell setNeedsLayout];
// returns my customized cell
return cell;
}
What happens is that everything works exactly how I want it to, however once I scroll down past around 100 cells or so the background of my app goes black for a few seconds and then I see my homescreen (I've seen some people call this the HSOD - home screen of death). Sometimes in the console in xcode I see memory warnings before a crash and sometimes I do not.
I know for a fact that whatever the problem is, it has to do with putting images into the cells. If I comment out just this line:
cell.preview.image = image;
Then everything works fine and it doesn't crash any more (but then of course the images are not being displayed in the cells).
The cells are being reused and I know that's working, for good measure I set the UIImageView's image property to nil:
- (void) prepareForReuse {
[super prepareForReuse];
if(self.preview != nil)
self.preview.image = nil;
}
and in my appDelegate I also define this:
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
[UIImageView clearAFImageCache];
}
Which deletes the image cache but that doesn't fix the problem either (and anyway iOS should clear the image caches upon memory warnings automatically anyway).
I ran analyze on my project and it reports no memory leaks, and here is the profiler showing that, as well as showing the allocations at the time of the crash:
Other than the occasional memory warning in the console which appears about 2/3rds of the time the app crashes, there are no other errors that appear in the console, and I do not hit any breakpoints or exceptions.
All of those allocations are you creating new table view cells each time they're requested, rather than reusing existing ones. Without setting a reuseIdentifier for cells created from UINib, dequeueReusableCellWithIdentifier: will always return `nil.
To fix this, add the following code (as referenced in this question):
[self.tableView registerNib:[UINib nibWithNibName:#"nibname"
bundle:nil]
forCellReuseIdentifier:#"cellIdentifier"];
I've found a solution, albeit not a perfect one:
The AFNetworking library is brilliant and I assume the cause of my problem lies within my own code or my lack of understanding as to how NSCache works.
AFNetworking caches images using Apple's NSCache. NSCache is similar to NSMutableDictionary, but releases objects when memory is spread thin (see more here).
Within UIImageView+AFNetworking.m I located the definition of
+ (AFImageCache *)af_sharedImageCache
And altered it to resemble this:
+ (AFImageCache *)af_sharedImageCache {
static AFImageCache *_af_imageCache = nil;
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_af_imageCache = [[AFImageCache alloc] init];
_af_imageCache.countLimit = 35;
});
return _af_imageCache;
}
The important line here is
_af_imageCache.countLimit = 35;
This tells the NSCache object being used in AFNetworking to cache images that it must only cache up to a maximum of 35 things.
For reasons unknown to me, iOS was not automatically purging objects from the cache as it should, and calling removeAllObjects on the cache was not working either. This solution is hardly ideal because it may not utilize the cache to its full potential or may over use the cache, but for the meantime it atleast stops the cache from attempting to store an infinite number of objects.

UICollectionView Data being Reordered

I am using a UICollectionView with a modified version of LXReorderableCollectionViewFlowLayout and data within my last two cells are being mixed up.
2 separate images are displayed in each cell, with a label beneath, and when I leave the viewController and return, I call reloadData. Every time this is called, the images in the cells swap. The labels, however, stay in the same place.
Here is the code I use to draw the cells which I have the issue with.
SettingsTile *setTileD = (SettingsTile *)[collectionView dequeueReusableCellWithReuseIdentifier:#"settingsReuse" forIndexPath:indexPath];
NSString *songTitle = [colors objectAtIndex:indexPath.row];
MPMediaQuery *query = [MPMediaQuery songsQuery];
[query addFilterPredicate:[MPMediaPropertyPredicate predicateWithValue:songTitle forProperty:MPMediaItemPropertyTitle]];
if ([query items].count > 0)
{
MPMediaItemArtwork *art = [[[query items] objectAtIndex:0] valueForProperty:MPMediaItemPropertyArtwork];
UIImage *im = [art imageWithSize:CGSizeMake(145, 145)];
setTileD.titleLabel.text = songTitle;
setTileD.titleLabel.textColor = [UIColor whiteColor];
UIImageView *imView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 145, 145)];
imView.image = im;
[setTileD addSubview:imView];
[setTileD sendSubviewToBack:imView];
return setTileD;
}
else
{
return nil;
}
The first time the app is run the images are mixed up, likely because viewDidAppear is also called when the viewController is first displayed, and when the user comes back to it, the images aren't mixed up. This process repeats itself.
reloadData is called as normal (e.g [collectionView reloadData]; ).
I'm new to UICollectionView, and it's accompanying classes, so please be kind. :)
I fixed the problem by putting the UIImageViews in a backgroundView, rather than adding them directly as subviews.
I can only imagine this problem is caused either by the way UICollectionView's cellForRowAtIndexPath: method grabs images as I call them, or the way LXReorderableCollectionViewFlowLayout works.

Resources