I've got this problem with a UICollectionView inside a UICollectionViewCell:
The last UICollectionViewCell doesn't get filled with 13 - 18, but instead, the first one get's copied.
I know it has something to do with "dequeueReusableCellWithReuseIdentifier" but if I don't do the check on the tag below, my entire collection gets messed up.
I've been struggling with this issue and Googling around for about a day now, but I can't find how to fix this.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellID=#"pageCell";
UICollectionViewCell *cell=[collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
int no = indexPath.item;
if(collectionView == _pageCollectionView)
{
//Collection pages
cell.tag=no+1;
UICollectionViewFlowLayout *layoutMods=[[UICollectionViewFlowLayout alloc] init];
[layoutMods setSectionInset:UIEdgeInsetsMake(0, 0, 0, 0)];
[layoutMods setMinimumInteritemSpacing:0];
[layoutMods setMinimumLineSpacing:0];
[layoutMods setItemSize:CGSizeMake(125, 125)];
_modsCollectionView=[[UICollectionView alloc] initWithFrame:CGRectMake(0,0, _pageCollectionView.frame.size.width, _pageCollectionView.frame.size.height) collectionViewLayout:layoutMods];
[_modsCollectionView setDataSource:self];
[_modsCollectionView setDelegate:self];
_modsCollectionView.pagingEnabled = YES;
[_modsCollectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"pageCell"];
NSMutableArray *randColor = [[NSMutableArray alloc] init];
for(int i=0;i<3;i++)
{
int lowerBound = 0;
int upperBound = 255;
NSNumber *rndValue = [NSNumber numberWithFloat:(lowerBound + arc4random() % (upperBound - lowerBound) )/255.0];
[randColor insertObject:rndValue atIndex:i];
}
float r = [[randColor objectAtIndex:0] floatValue];
float g = [[randColor objectAtIndex:1] floatValue];
float b = [[randColor objectAtIndex:2] floatValue];
_modsCollectionView.backgroundColor = [UIColor colorWithRed:r green:g blue:b alpha:1];
[cell addSubview:_modsCollectionView];
}
else
{
if(cell.tag == 0)
{
cell.tag = 2;
NSMutableDictionary *mod=[modules objectAtIndex:modulePointer];
cell.backgroundColor=[mod objectForKey:#"color"];
NSString *slug = [mod objectForKey:#"slug"];
NSString *imgName=[NSString stringWithFormat:slug,#".png"];
UIImageView *customBackground = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imgName]];
customBackground.frame = CGRectMake(0,0, 125, 125);
[cell addSubview:customBackground];
customBackground.contentMode = UIViewContentModeScaleAspectFit;
customBackground.clipsToBounds = YES;
modulePointer++;
}
}
return cell;
}
What am I doing wrong?
Got it! I had to work some magic using view tags inside - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath.
In the if(collectionView == _pageCollectionView) i put:
for(id subview in [cell subviews])
{
[subview removeFromSuperview];
}
cell.tag=itemsPerScreen*no;
And then in the following else:
int thisIndex=[collectionView superview].tag+no;
NSMutableDictionary *mod=[modules objectAtIndex:thisIndex];
You need to create your own custom UICollectionViewCell to prevent this from happening.
Related
I'm trying to get collection view cells with a background image and text on them. When I build and run it sometimes they show up in the simulator and sometimes they don't even when I don't change the code.
- (void)viewDidLoad
{
[super viewDidLoad];
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat frameWidth = screenRect.size.width - 40;
CGFloat frameHeight = screenRect.size.height - 20;
_collectionView=[[UICollectionView alloc] initWithFrame:CGRectMake(20, 20, frameWidth, frameHeight) collectionViewLayout:layout];
[_collectionView setDataSource: self];
[_collectionView setDelegate: self];
[_collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"cellIdentifier"];
[_collectionView setBackgroundColor:[UIColor clearColor]];
[self.view addSubview:_collectionView];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return [self.articles count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellIdentifier" forIndexPath:indexPath];
UILabel *articleTitle = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, 40)];
NSDictionary *article = self.articles[indexPath.row];
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: article[#"image"]]];
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageWithData:imageData]];
articleTitle.text = article[#"title"];
articleTitle.textColor = [UIColor whiteColor];
[cell.contentView addSubview:articleTitle];
return cell;
}
"articles" is a json object with title, image and url keys. They seem to work when the cells show up but as I said they don't always show.
This is my first app so any help would be really appreciated.
The numbers of section will be depend on article count.
Try placing breakpoint in there, your article array might be empty, if so collection view data source will not get any data to be displayed.
Or if self.articel refers to an array then try replacing line
NSDictionary *article = self.articles[indexPath.row];
With
NSDictionary *article = [self.articles objectatIndexPath:indexPath.row];
Or post your full code so we could see for other possible bug.
CollectionView horizontal scroll not working in ios 7 but it's working fine in ios 8 and 9. Is there any solution for this ?
The Code is here:
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
layout.itemSize = CGSizeMake(330, 100);
collection = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0, 50.0, 350, 100) collectionViewLayout:layout];
collection.delegate = self;
collection.dataSource = self;
collection.backgroundColor = [UIColor greenColor];
collection.pagingEnabled = YES;
[collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
[self.view addSubview:collection];
It now fits my needs, and could be useful for someone else, so here is my code:
I have tested In iOS7-8-9. Below example is for Default iPad. You Just need to change target settings and O.S Version.
https://github.com/philippeauriach/fullyhorizontalcollectionview
Please download it & let us know ur comments. Happy Coding!
If you want to add collection view onto the View then use below code. Below code into i have created CL View programmatically and It's also working correctly with Autolayout and iOS 7-8-9. Please implement below code and let us know ur comments.
.H File
#interface HorizontalCollectionViewController : UIViewController<UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout>{
NSIndexPath *visibleIndexPath;
}
#property (nonatomic, assign) NSInteger selectedCell;
#property (strong, nonatomic) IBOutlet UICollectionView *horizonCLView;
.M File
#import "HorizontalCollectionViewController.h"
static NSString * const CellIdentifier = #“horizonCell";
#interface HorizontalCollectionViewController ()
#end
#implementation HorizontalCollectionViewController
#synthesize horizonCLView;
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"view frame : %#",NSStringFromCGRect(self.view.frame));
[self.view layoutIfNeeded];
[self.view setNeedsLayout];
[self viewDidLayoutSubviews];
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
layout.itemSize = self.view.frame.size;
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[layout setMinimumInteritemSpacing:0.f];
[layout setMinimumLineSpacing:0.f];
layout.sectionInset = UIEdgeInsetsMake(0, 0, 0, 0);
horizonCLView = [[UICollectionView alloc] initWithFrame:self.view.frame collectionViewLayout:layout];
horizonCLView.dataSource = self;
horizonCLView.delegate = self;
horizonCLView.backgroundColor = [UIColor lightGrayColor];
horizonCLView.scrollEnabled = YES;
[horizonCLView setBounces:NO];
[horizonCLView setUserInteractionEnabled:YES];
[horizonCLView setPagingEnabled:YES];
[horizonCLView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:CellIdentifier];
[self.view addSubview:horizonCLView];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)viewWillAppear:(BOOL)animated{
//Select Current Image For Sare In Social Media
// currentImageIndex = selectedCell;
[horizonCLView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:selectedCell inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
CGRect visibleRect = (CGRect){.origin = self.horizonCLView.contentOffset, .size = self.horizonCLView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
visibleIndexPath = [self.horizonCLView indexPathForItemAtPoint:visiblePoint];
// NSLog(#"visibleIndexPath.row in View will appear %ld",(long)visibleIndexPath.row);
//SelectedCell is a selected image from gallary view
NSLog(#"selectedCell in View will appear: %ld",(long)selectedCell);
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return [dataAry count];
}
#pragma Here we set the frame of horizontal scrll view
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
// expand cell to fill the entire view
return collectionView.frame.size;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
self.title = [[self.dataAry objectAtIndex:indexPath.row] valueForKey:#“dataAryName"];
//imageVI.image = nil;
imageVI = (UIImageView *)[cell.contentView viewWithTag:100];
if (!imageVI){
imageVI = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,self.view.bounds.size.width,self.view.bounds.size.height)];
imageVI.contentMode = UIViewContentModeScaleAspectFill;
imageVI.tag = 100;
imageVI.clipsToBounds = YES;
[cell.contentView addSubview:imageVI];
}
dispatch_async(dispatch_get_main_queue(), ^{
[asSetLib assetForURL:[NSURL URLWithString:[[self.dataAry objectAtIndex:indexPath.row] valueForKey:#"dataAryName"]] resultBlock:^(ALAsset *asset) {
// imageVI.image = [UIImage imageWithCGImage:asset.defaultRepresentation.fullScreenImage];
imageVI.image = [UIImage imageWithCGImage:asset.defaultRepresentation.fullResolutionImage];
NSLog(#"Preview view into album loaded successfully!");
} failureBlock:^(NSError *error) {
NSLog(#"An error occurred while loading image: %#", error.description);
}];
});
return cell;
}
Sudha, I think this issues in your code not an iOS7 issues.
Here, I have review two bug in ur code.
1)In this line you have give static width of collection view,
collection = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0, 50.0, 350, 100) collectionViewLayout:layout];
Instead Of it will be goes look like,
collection = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0, 50.0, self.view.bounds.size.width, 100) collectionViewLayout:layout];
Make sure your collection view width size always go with according to your view size.
2)Make sure, Your layout item size width higher then collection view width frame. Otherwise Scrolling was not effected.
layout.itemSize = CGSizeMake(self.view.bounds.size.width+10, 100);
3) Carefully use,
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
delegate method of collectionview layout size method.
4)Finally your code look like,
- (void)viewDidLoad {
[super viewDidLoad];
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(self.view.bounds.size.width+10, 100);
[layout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
collection = [[UICollectionView alloc] initWithFrame:CGRectMake(0.0, 50.0, self.view.bounds.size.width, 100) collectionViewLayout:layout];
collection.delegate = self;
collection.dataSource = self;
collection.backgroundColor = [UIColor greenColor];
collection.pagingEnabled = YES;
collection.scrollEnabled = YES;
collection.userInteractionEnabled = YES;
[collection registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:#"Cell"];
[self.view addSubview:collection];
}
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return 1;
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
return cell;
}
Happy Coding!
I've used a line of code after adding collectionView on view that its working fine in ios 7 also.
add this code after [self addSubview:self.collectionView];
here the code:
[self performSelector:#selector(update) withObject:nil afterDelay:1];
(void)update {
[self.collectionView setContentOffset:CGPointMake(1, 0)];
}
I have a collectionview that will be a menu with two columns, without spacing: so each cell with width 160. And I need a line separating each cell.
Each cell contains an imageview and a label.
I'm trying to add a line separator between the cells like this: How to add views between UICollectionViewCells in a UICollectionView?
But the result is:
Code:
- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
return UIEdgeInsetsMake(0, 0, 0, 0);
}
- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section {
return 2;
}
// 2
- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView {
return [options count];
}
// 3
- (UICollectionViewCell *)collectionView:(UICollectionView *)cv cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"MenuOptionCell";
UICollectionViewCell *cell = [self.menu dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
UIImageView *img = (UIImageView*) [cell viewWithTag:100];
UILabel *lbl = (UILabel*) [cell viewWithTag:90];
UIView *seperatorView = [[UIView alloc] initWithFrame:CGRectMake(cell.frame.origin.x+10, cell.frame.origin.y+cell.frame.size.height, cell.frame.size.width-10, 1)];
seperatorView.backgroundColor = [UIColor whiteColor];
[self.menu addSubview:seperatorView];
[self.menu bringSubviewToFront:seperatorView];
UIView *seperatorView2 = [[UIView alloc] initWithFrame:CGRectMake(cell.frame.origin.x+cell.frame.size.width-10, cell.frame.origin.y, 1, cell.frame.size.height)];
seperatorView.backgroundColor = [UIColor whiteColor];
[self.menu addSubview:seperatorView2];
[self.menu bringSubviewToFront:seperatorView2];
lbl.text = #"TEST";
img.image = [UIImage imageNamed:#"test.png"];
return cell;
}
I have a UICollectionView that i set up in the viewDidLoad and add the images immediately after that. When the user scrolls to a certain point i try to add more images but The collection view won't load the new images
How do i reload or add more images to my scrollview
#pragma mark - New Retrieve
- (void) rwDataToPlist {
// Step1: Get plist file path
NSArray *sysPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory ,NSUserDomainMask, YES);
NSString *documentsDirectory = [sysPaths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"news.plist"];
NSLog(#"Plist File Path: %#", filePath);
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
stuff = [[NSArray alloc] initWithContentsOfFile:filePath];
//NSLog(#"Stuff %#", stuff);
[self sortRetrievedData];
} else {
}
}
-(void)sortRetrievedData {
titles = [stuff valueForKey:kKeyTitle];
thumbMediaUrl = [stuff valueForKey:kKeyThumbUrl];
thumbWidth = [stuff valueForKey:kKeyThumbWidth];
thumbHeight = [stuff valueForKey:kKeyThumbHeight];
for(NSArray *array in titles) {
for (NSArray *realArray in array) {
titles = realArray;
}
}
for(NSArray *array in thumbMediaUrl) {
for(NSDictionary *dict in array) {
thumbMediaUrl = dict;
}
}
for(NSArray *array in thumbWidth) {
for(NSDictionary *dict in array) {
thumbWidth = dict;
}
}
for(NSArray *array in thumbHeight) {
for(NSDictionary *dict in array) {
thumbHeight = dict;
}
}
}
#pragma mark - Collection View
#pragma mark - Display Collection
-(void)displayCollection {
UIColor *myColor = [UIColor colorWithRed:(245.0 / 255.0) green:(245.0 / 255.0) blue:(245.0 / 255.0) alpha: 1];
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
CGFloat screenHeight = screenSize.height;
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
CGRect locOfScree = CGRectMake(0, 64, screenWidth, screenHeight - 44);
UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
imageDisplayer = [[UICollectionView alloc] initWithFrame:locOfScree collectionViewLayout:layout];
[imageDisplayer setDataSource:self];
[imageDisplayer setDelegate:self];
UINib *nib = [UINib nibWithNibName:#"CollectionViewCell" bundle:nil];
[imageDisplayer registerNib:nib forCellWithReuseIdentifier:CellIdentifier];
[imageDisplayer setBackgroundColor:myColor];
[self.view insertSubview:imageDisplayer belowSubview:navBar];
//[self.view addSubview:imageDisplayer];
}
#pragma mark - Setup
- (void)setupData
{
self.imageURLStrings = [NSMutableArray array];
// Save image to docs directory so we can get a nice URL
// Not sure how to get the URL from an asset catalog off the top of my head
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:#"greyBurger.png"];
UIImage *image = [UIImage imageNamed:#"greyBurger"];
NSData *data = UIImagePNGRepresentation(image);
[data writeToFile:path atomically:YES];
// Populate our imageURLStrings array with many paths
for (NSInteger i = 0; i < NumberOfImages; i++)
{
[self.imageURLStrings addObject:path];
//NSLog(#"Path %#", path);
}
}
- (void)setupCollectionView
{
UINib *nib = [UINib nibWithNibName:#"CollectionViewCell" bundle:nil];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:CellIdentifier];
}
#pragma mark - UICollectionView Datasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
//return [self.imageURLStrings count];
return [titles count];
//return 2;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
//NSLog(#"CELL FOR COUNT:%lu", [titles count]);
NSString *title = [titles objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor whiteColor];
NSString *imageUrl = [thumbMediaUrl objectForKey:title];
NSURL *thumbUrl = [NSURL URLWithString:imageUrl];
UIImageView *imageView = [[UIImageView alloc] init];
NSData *imageData = [NSData dataWithContentsOfURL:thumbUrl];
imageView.image = [UIImage imageWithData:imageData];
cell.backgroundView = imageView;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
//cell.frame = CGRectMake(0, 0, 100, 100);
//cell.imageURLString = [self.imageURLStrings objectAtIndex:indexPath.item];
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
NSString *title = [titles objectAtIndex:indexPath.row];
float width = [[thumbWidth objectForKey:title] floatValue];
float height = [[thumbHeight objectForKey:title] floatValue];
float imageWidth = (screenWidth / 2) - 3;
float scale = imageWidth / width;
float imageHeight = height * scale;
CGSize imageSize = CGSizeMake(imageWidth, imageHeight);
return imageSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 2.0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 2.0;
}
// Layout: Set Edges
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
// return UIEdgeInsetsMake(0,8,0,8); // top, left, bottom, right
return UIEdgeInsetsMake(0,0,0,0); // top, left, bottom, right
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray* attributesToReturn = [self layoutAttributesForElementsInRect:rect];
for (UICollectionViewLayoutAttributes* attributes in attributesToReturn)
{
if (nil == attributes.representedElementKind)
{
NSIndexPath* indexPath = attributes.indexPath;
attributes.frame = [self layoutAttributesForItemAtIndexPath:indexPath].frame;
}
}
return attributesToReturn;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes* currentItemAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];
if (indexPath.item < numColumns){
CGRect f = currentItemAttributes.frame;
f.origin.y = 0;
currentItemAttributes.frame = f;
return currentItemAttributes;
}
NSIndexPath* ipPrev = [NSIndexPath indexPathForItem:indexPath.item-numColumns inSection:indexPath.section];
CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame;
CGFloat YPointNew = fPrev.origin.y + fPrev.size.height + 10;
CGRect f = currentItemAttributes.frame;
f.origin.y = YPointNew;
currentItemAttributes.frame = f;
return currentItemAttributes;
}
I have changed my code based on suggestions of The first two answers, now i have to to get the images to add to a running view. and make each column have their own independent height so there is a 2px spacing at each edge, This is what i tried for reloading data
-(void)refreshView {
[self rwDataToPlist];
[self.collectionView reloadData];
[self setupCollectionView];
}
With starting iOS6 itself Apple Introduced for UICollectionView. You can Use UICollectionView with Pull to Bottom Refresh to Achieve your Goal. Its look like UITableView Pull to Bottom Refresh.
Here Are Some Reference for UIcollectionView:
Source Code
Beginning UICollectionView
UICollectionView with StoryBoard
Once You create UICollectionView then You need to Add PulltoBottom Refresh for your UICollectionView like following code:
-(void)viewWillAppear:(BOOL)animated
{
[self.collectionView.infiniteScrollingView setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhite];
[self.collectionView addInfiniteScrollingWithActionHandler:^{
////(#"Infinitescroll");
#try {
int64_t delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
//[self.dataSource addObjectsFromArray:tmp];
[self.collectionView performBatchUpdates:^{
} completion:nil];
[self.collectionView.infiniteScrollingView stopAnimating];
});
}
#catch (NSException *exception) {
}
}];
[super viewWillAppear:animated];
}
For Below code you must Add some files:
SVPulltoReferesh Link
A few suggestions / questions:
Not knowing the constraints of your particular problem, it sounds like you're trying to display some semblance of a grid of images, and load the "next page" of images when a user scrolls beyond a certain point. It seems like a UITableView or UICollectionView would be a more appropriate mechanism to do what you're trying to do. Both of those classes will handle lazy loading of images, pagination via a properly configured datasource, automatic contentSize adjustments, and will be blazing fast without mainThread freezes. They're also based on the MVC design pattern and will likely clarify some of the design in the code above.
The reason the UI/scrolling freezes when you load more images is likely due to reading both userDefaults and the image data itself from disk. Disk operations can be expensive, especially many at a time. If you must load the metadata and image files this way, consider doing this processing on a background thread via GCD's dispatch_async.
The reason the second set of images is not appearing is likely due to image frame or scrollView contentSize miscalculation. Consider debugging by adding a series of colored UIViews to the scrollView instead of UIImageViews, and consider hard coding the contentSize.height to something much larger than you need. Also, have you NSLogged the image frames and contentSize to make sure they match up?
Edit:
Here's a link to a quick sample project using a UICollectionView and a background thread for reading UIImage data from disk (which isn't really necessary anymore due to using UICollectionView):
https://github.com/alfiehanssen/SOImageGrid
Let me know if you have questions, hopefully I'm not totally off the mark in terms of your goals.
I used a UICollectionView as suggested in the first two answers and added CHTCollectionViewWaterfallLayout to it to allow the image spacing i wanted
My Code:
#pragma mark - Collection View
#pragma mark - Display Collection
-(void)displayCollection {
UIColor *myColor = [UIColor colorWithRed:(245.0 / 255.0) green:(245.0 / 255.0) blue:(245.0 / 255.0) alpha: 1];
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
CGFloat screenHeight = screenSize.height;
self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
CGRect locOfScree = CGRectMake(0, 44, screenWidth, screenHeight - 44);
CHTCollectionViewWaterfallLayout *layout = [[CHTCollectionViewWaterfallLayout alloc] init];
layout.sectionInset = UIEdgeInsetsMake(2, 2, 2, 2);
layout.headerHeight = 0;
layout.footerHeight = 0;
layout.minimumColumnSpacing = 2;
layout.minimumInteritemSpacing = 2;
//UICollectionViewFlowLayout *layout=[[UICollectionViewFlowLayout alloc] init];
imageDisplayer = [[UICollectionView alloc] initWithFrame:locOfScree collectionViewLayout:layout];
imageDisplayer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[imageDisplayer setDataSource:self];
[imageDisplayer setDelegate:self];
UINib *nib = [UINib nibWithNibName:#"CollectionViewCell" bundle:nil];
[imageDisplayer registerNib:nib forCellWithReuseIdentifier:CellIdentifier];
[imageDisplayer setBackgroundColor:myColor];
[self.view insertSubview:imageDisplayer belowSubview:navBar];
//[self.view addSubview:imageDisplayer];
imageDisplayer = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
imageDisplayer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imageDisplayer.dataSource = self;
imageDisplayer.delegate = self;
imageDisplayer.backgroundColor = [UIColor whiteColor];
[imageDisplayer registerClass:[CHTCollectionViewWaterfallCell class]
forCellWithReuseIdentifier:CellIdentifier];
}
#pragma mark - Setup
- (void)setupCollectionView
{
UINib *nib = [UINib nibWithNibName:#"CollectionViewCell" bundle:nil];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:CellIdentifier];
}
#pragma mark - UICollectionView Datasource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
//return [self.imageURLStrings count];
return [titles count];
//return 2;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
/*
CollectionViewCell *cell = (CollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
*/
CHTCollectionViewWaterfallCell *cell =
(CHTCollectionViewWaterfallCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier
forIndexPath:indexPath];
NSString *title = [titles objectAtIndex:indexPath.row];
cell.backgroundColor = [UIColor whiteColor];
NSString *imageUrl = [thumbMediaUrl objectForKey:title];
NSURL *thumbUrl = [NSURL URLWithString:imageUrl];
UIImageView *imageView = [[UIImageView alloc] init];
NSData *imageData = [NSData dataWithContentsOfURL:thumbUrl];
imageView.image = [UIImage imageWithData:imageData];
cell.backgroundView = imageView;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
return cell;
}
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath
{
CGRect screenBound = [[UIScreen mainScreen] bounds];
CGSize screenSize = screenBound.size;
CGFloat screenWidth = screenSize.width;
NSString *title = [titles objectAtIndex:indexPath.row];
float width = [[thumbWidth objectForKey:title] floatValue];
float height = [[thumbHeight objectForKey:title] floatValue];
float imageWidth = (screenWidth / 2) - 3;
float scale = imageWidth / width;
float imageHeight = height * scale;
CGSize imageSize = CGSizeMake(imageWidth, imageHeight);
return imageSize;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
return 2.0;
}
- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
return 2.0;
}
// Layout: Set Edges
- (UIEdgeInsets)collectionView:
(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
// return UIEdgeInsetsMake(0,8,0,8); // top, left, bottom, right
return UIEdgeInsetsMake(0,0,0,0); // top, left, bottom, right
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSArray* attributesToReturn = [self layoutAttributesForElementsInRect:rect];
for (UICollectionViewLayoutAttributes* attributes in attributesToReturn)
{
if (nil == attributes.representedElementKind)
{
NSIndexPath* indexPath = attributes.indexPath;
attributes.frame = [self layoutAttributesForItemAtIndexPath:indexPath].frame;
}
}
return attributesToReturn;
}
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewLayoutAttributes* currentItemAttributes = [self layoutAttributesForItemAtIndexPath:indexPath];
if (indexPath.item < numColumns){
CGRect f = currentItemAttributes.frame;
f.origin.y = 0;
currentItemAttributes.frame = f;
return currentItemAttributes;
}
NSIndexPath* ipPrev = [NSIndexPath indexPathForItem:indexPath.item-numColumns inSection:indexPath.section];
CGRect fPrev = [self layoutAttributesForItemAtIndexPath:ipPrev].frame;
CGFloat YPointNew = fPrev.origin.y + fPrev.size.height + 10;
CGRect f = currentItemAttributes.frame;
f.origin.y = YPointNew;
currentItemAttributes.frame = f;
return currentItemAttributes;
}
i have a tableview. i add image to the cells when clicked on the cell in didselectrow method by using cell.conteview addsubview. but the problem is if i click on 1st cell it changes the image and when i click on another cell image will appears but the old image is not removed from the previous cell. This is happening for all cells in table view if a cell is clicked.
i used the code as follows
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
Practices *bPractices = [topics objectAtIndex:indexPath.row];
UIImageView *clickView;
//[cell.contentView removeFromSuperview];
clickView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 315, 82)];
clickView.image = [UIImage imageNamed:#"list_bg_hover.png"];
[cell.contentView addSubview:clickView];
[clickView release];
UILabel *labelText= [[UILabel alloc]initWithFrame:CGRectMake(90, 30, 320, 20)];
labelText.text=bPractices.practices_title;
labelText.backgroundColor=[UIColor clearColor];
[cell.contentView addSubview:labelText];
}
pls help me how to solve this issue
Thanks in advance
I did something similar, but not with images but buttons. If a cell wasn't selected yet and gets tabbed, the size is changed and a certain and individual number of buttons is added. If another cell was selected, this one gets closed.
Code from form the UITableViewController
interface:
int openedCellIndex;//<-what cell is selected
int buttonCounter;
implementation:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( indexPath.row != openedCellIndex )
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[TRTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier]
autorelease];
//cell.frame = CGRectMake (0,0, 320, 100);
}
id <P_E_P1Article> article = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = article.name;
if ( self.cellBackgroundColor )
cell.backgroundColor = self.cellBackgroundColor;
return cell;
}
else {
//get article
id <P_E_P1Article> article = [self.fetchedResultsController objectAtIndexPath:indexPath];
//number of buttons
int buttons = [article.specification count];
int height = 50 * ceil(buttons / 2) + 50;
//construct special cell
UITableViewCell *cell = [[[TRTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:#"CellBig"]
autorelease];
cell.frame = CGRectMake (0,0, 320, 150);
cell.textLabel.text = #"";
//add label
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 10, 280, 30)];
label.font = [UIFont boldSystemFontOfSize:17];
label.text = article.name;
label.backgroundColor = [UIColor clearColor];
[cell addSubview:label];
[label release];
if ( buttonMapper == nil )
self.buttonMapper = [NSMutableDictionary dictionaryWithCapacity:10];
//NSLog (#" bla: %#", article.isFreePrice);
//see if we have a free prized article
//create the buttons
NSEnumerator *enumerator = [article.specification objectEnumerator];
id <P_E_P1ArticleSpecification> spec;
int count = 0;
NSArray *specs =
[self sortedArticleSpecifications:article];
for ( spec in specs ) {
//see which row and col the button is in
int row = floor ( count / 2 );
int col = count % 2;
//define button position
int left = 20 + col * 145;
int top = 45 + row * 50;
//create button
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(left, top, 135, 40);
[cell addSubview:button];
[button setTitleColor:[UIColor blackColor] forState:0];
[button addTarget:self
action:#selector(buttonTapped:)
forControlEvents:UIControlEventTouchUpInside];
//remember which article the button is attached to
buttonCounter++;
button.tag = buttonCounter;
[buttonMapper setValue:spec forKey:[NSString stringWithFormat:#"bla%d",buttonCounter]];
count++;
}
if ( self.cellBackgroundColor )
cell.backgroundColor = self.cellBackgroundColor;
return cell;
}
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( openedCellIndex == indexPath.row )
{
id <P_E_P1Article> article = [self.fetchedResultsController objectAtIndexPath:indexPath];
int count = [article.specification count];
int height = 50 * ceil(count / 2.) + 50;
return height;
}
return 50;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
[self openRow:indexPath.row];
[self.searchBar resignFirstResponder];
}
- (void) openRow:(int) index
{
if ( index == openedCellIndex ) return;
int oldIndex = openedCellIndex;
openedCellIndex = index;
NSUInteger indexArr[] = {0, oldIndex};
NSIndexPath *oldPath = [NSIndexPath indexPathWithIndexes:indexArr length:2];
NSUInteger indexArr2[] = {0, openedCellIndex};
NSIndexPath *newPath = [NSIndexPath indexPathWithIndexes:indexArr2 length:2];
//update view
[(UITableView *)self.view beginUpdates];
if ( oldIndex >= 0 )
[(UITableView *)self.view reloadRowsAtIndexPaths:[NSArray arrayWithObject:oldPath]
withRowAnimation:UITableViewRowAnimationFade];
if (openedCellIndex >=0 )
[(UITableView *)self.view reloadRowsAtIndexPaths:[NSArray arrayWithObject:newPath]
withRowAnimation:UITableViewRowAnimationFade];
[(UITableView *)self.view endUpdates];
}
You could also subclass UITableViewCell and handle the select/deselect process in the setSelected method. Then use your custom cell as the type for the prototype cell instead of the default.