iOS: crash in collectionview reoloaddata with UIImage - ios

In my app I have this code:
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return images.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *identifier = #"gallerycell";
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *backImageCell = (UIImageView*)[cell viewWithTag:100];
[backImageCell setImage:[images objectAtIndex:indexPath.item]];
if([indexPath row] == ((NSIndexPath*)[[collectionView indexPathsForVisibleItems] lastObject]).row){
[activity_view stopAnimating];
[UIView animateWithDuration:0.8 animations:^{
back.alpha = 0;
}];
}
return cell;
}
the array images contains UIImage of 200x150 size, and their dimension in kb is about 42kb, a normal array of UIImage.
When I reload data for this collectionview I have a memory warning after 15 image... is there a way (as a thread) to don't have a memory warning?

Don't store Images to Array, that's not a good practice. As the number of images or size of images increase it'll throw memory warnings and crash.
Alternatives:
Store image names in array
Store file path in array
Store image url in array and use Async methods to load the image to your UITableView or UICollectionView

In addition to resizing the images, you can nil out the image when the cell scrolls out of view - just implement:
- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
Also, a trick to maintain a cache that will not swamp the system is to do as Midhun suggested in the comments - use imageWithContentsOfFile. Then create a NSCache, and stuff the images in it using the image name or some other identifying key. When you need an image, if its in the cache, pull it out. If not you can read it from the file system again. iOS will purge a NSCache if it needs more memory.

Related

Loading images in collectionView

Each UITableViewCell contains a UICollectionView. Having trouble figuring out why some UICollectionViewCell images are not showing up. I'm using SDWebImage library to load images. The method - (void)sd_setImageWithURL:(NSURL *)urlcalls [self sd_cancelCurrentImageLoad];. I think cancelling the previous request is the problem, but read somewhere that will create a race condition. Problem doesnt happen for every UITableViewCell, and if I tap on cell for details and go back, the images fill in. Perhaps I need to reload data somewhere. Any tips on how to solve this?
if you try to image fatch from server to try this.
#import "UIImageView+WebCache.h"
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NewProfileCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
[cell.img_user_image sd_setImageWithURL:[NSURL URLWithString:[mutDict valueForKey:#"UserImageURL"][indexPath.row]] placeholderImage:[UIImage imageNamed:#"No_IMAGE_PLACE"]];
return cell;
}
Try it:
- (void)prepareForReuse
{
[super prepareForReuse];
[self.imageView cancelCurrentImageLoad];
[self.imageView setImage:[UIImage imageNamed:#""] forState:UIControlStateNormal]; // Placeholder image
}

CollectionView dequeCell with removing subviews from cell makes view appear slow

I have code:
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return 30;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:REUSE_IDENTIFIER forIndexPath:indexPath];
[[cell subviews]
makeObjectsPerformSelector:#selector(removeFromSuperview)];
[cell addSubview:someView];
return cell;
}
Above code gets executed in viewWillAppear
If I make the above code executed 30 times, the view appearance is really slow.
Due to cell reuse, I need to make a call to removeFromSuperView. Otherwise stale wrong data is displayed on the cell.
I am not able to figure out what could be causing the slowness??
Can you provide hints?
Your appearance is slow because you are iterating through all the subviews within the cell and removing from superview. This is a very expensive process and should not be done in the cellForItemAtIndexPath method of the collectionView data source/ Infact this should never be done. If you need to display relevant content you need to access the instance of the cell and update the properties of the UI elements within the cell.

How To Insert Item in UIcollectionview after downloading data

Friends here I am using UICollectionview to show images but my images are coming from web services.
now the problem is that I got all data from the net but how I can insert item in UICollectionview.
I know insertItemAtIndexPath method but don't know where and how to use it.
Please help me out.
Thanks in advance.
You could use the delegate pattern in order to download your data.
The delegate will prevent the class that implements the protocol that the download is finished so you can load data through the method called with [YouCollectionView reloadData]
and to display your image, your collectionView could be based on an array, so for example, the delegate could send a array with your image/url.
/*! This delegate method is called when the items have been downloaded. They're then stored into an array.*/
- (void)didDownloadItems:(NSMutableArray*)responseArray{
_imgArray = responseArray;
[yourCollectionView reloadData];
}
and then in your : (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
UICollectionViewCell *cell = [yourCollectionView dequeueReusableCellWithReuseIdentifier:cellIdentifier forIndexPath:indexPath];
// Retrieve the img
UIImage *img = [_imgArray objectAtIndex:indexPath.row];
//do your stuff with the img
return cell;
}

Use uicollectionview inside uitableviewcell

I can't solve next problem.
I want to display 20 table cells, each contains a unique UICollectionView.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *package=[_packageList objectAtIndex:indexPath.row];
static NSString *CellIdentifier = #"package";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UICollectionView *cellImageCollection=(UICollectionView *)[cell viewWithTag:9];
cellImageCollection.restorationIdentifier=[NSString stringWithFormat:#"%li", (long)indexPath.row, nil];
cellTracking.text=[NSString stringWithFormat:#"Row #%li",(long)indexPath.row];
return cell;
}
-(NSInteger) collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
int row=[collectionView.restorationIdentifier intValue];
return [[[_packages objectAtIndex:row] valueForKey:#"imageGallery"] count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
int row=[collectionView.restorationIdentifier intValue];
NSString *imgStrLink=[[[_packages objectAtIndex:row] valueForKey:#"imageGallery"] objectAtIndex:indexPath.row];
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"ImageID" forIndexPath:indexPath];
UIImageView *imageView=(UIImageView *)[cell viewWithTag:2];
imageView.image=....;
return cell;
}
Function tableView:cellForRowAtIndexPath: is called 20 times, but collectionView:numberOfItemsInSection: and collectionView:cellForItemAtIndexPath: only 4 times.
As seen in the screenshots UICollectionView is repeated every fourth line.
What is my fault?
I too faced this problem, the reason I got this problem was because both datasource and delegates for the tableview and collectionView were to the same parent viewcontroller.
It started working for me when I changed the datasource and delegate of the collectionView to another View say ParentView, and I added the collectionView to this ParentView and then finally added ParentView as conentView of the cell.
My previous answer which points to two nice tutorials was deleted by someone saying that I should include the essential parts of the content here(because the link may become invalid in future)...but I cannot do that as those are codes written by the tutorial owners and also the whole codes are essential too :), so now I am giving the link to the source code...
HorizontalCollectionViews
AFTabledCollectionView
-anoop
since Xcode 7 and iOS9 you can use UIStackView - best solution for design if collectionview or tableview are containing each other.

xcode how to display images in collection view cell from database

I am just a beginner. i want to display image which is stored in database in a collection view cell. I have already created database and collection view. my code is as follow,
MyDatabase *data;
data=[MyDatabase new];
imagearray=[data OpenMyDatabase:#"SELECT pic_name FROM exterior" :#"pic_name"];
so my question is how can i display images ? let me know the way/code
thanks in advance
You can use following code for display UIImage grid. Add UICollectionView for your xib file. Don't forget to set the delegate in collection.
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return noOfItem/ noOfSection;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView
numberOfItemsInSection:(NSInteger)section
{
return noOfSection;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView
cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"Cell";
UICollectionViewCell *cell =
[collectionView dequeueReusableCellWithReuseIdentifier:identifier
forIndexPath:indexPath];
UIImageView *recipeImageView = (UIImageView *)[cell viewWithTag:100];
recipeImageView.image = [imageArray objectAtIndex:
(indexPath.section * noOfSection + indexPath.row)];
return cell;
}
In your xib file add UIImageView to your CollectionViewCell and change it tag value to 100.
Please go through below links.
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UICollectionView_class/Reference/Reference.html
Above link is from Apple developer site. It has all details of UIcollectionview and tutorials related it. Below URL is also having sample tutorial, which will help you a lot.
http://www.raywenderlich.com/22324/beginning-uicollectionview-in-ios-6-part-12
You have images array retrieved from database. Now it will act as data source for collection view. You need to form UICollectionViewCell which will have those images accordingly. Please study above links, you will get to know.

Resources