I have checked alot of the questions that answer this but I believe I have a special case.
I want to caveat this by saying that I was working on an app with a friend and he went to work for Apple. I was the designer and he was the developer. He was teaching me Objective-C and Swift. I am updating the app he and I worked on and trying something new with it. Probably way over my head but I am learning alot by working on it and doing tutorials # Udemy and asking questions with other developers I know.
So I have a cirumstance where the app is using a UICollectionView to display a collection of "items". When you tap a "item" it animates to a detail view of that item and gives you more information. Cell reuse wasn't a problem until I built out a way to swipe between the items at the detail level. (You can tap into an item detail and then swipe between those details.)
Here is the problem: if the cell of the item isn't on screen when a user moves to the detail view and tries to swipe to that item it won't be displayed.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
KNIIssueCollectionViewCell *cell = (KNIIssueCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:kItemCellReuseID forIndexPath:indexPath];
KNIRecommendedItem *item = self.issue.items[indexPath.item];
[cell configureWithItem:item];
KNIRecommendedItemDetailViewController *itemDetailVC = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:NSStringFromClass([KNIRecommendedItemDetailViewController class])];
itemDetailVC.item = item;
itemDetailVC.transitioningDelegate = self;
itemDetailVC.itemImage = cell.image;
[self.pages addObject:itemDetailVC];
return cell;
}
I understanding the dequeueReusableCellWithReuseIdentifier should be removed, but every re-write I have tried resulted in errors.
- (UICollectionViewCell *)collectionView:(UICollectionView
*)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
KNIIssueCollectionViewCell *cell = //create new cell instance here
KNIRecommendedItem *item = self.issue.items[indexPath.item];
[cell configureWithItem:item];
// ...other part of code... //
return cell;
}
Related
I wonder which's the easiest way to have two different UICollectionViewCells-identifiers in the same UICollectionView? I've got an UISegmentedController that I want to switch between to different styles of UICollectionViewCells.. Where to implement which code. I've got an PatternViewCell for the first Cell but how do i do with the other? Please advice!
You can have two collection view cell prototypes registered for a single cell class for a single collection view with a single data source.
First, in your storyboard, set Cell1 as a reuse identifier for the first cell prototype and Cell2 for the second one. Both of them should have PatternViewCell class.
Then, on changing value of your segmented control you reload your collection view:
- (IBAction)segmentedControlValueChanged:(id)sender {
[self.collectionView reloadData];
}
Bind this action to your segmented control for the Value Changed event.
Then in - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath method you can choose a reuse identifier depending on selected index.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
NSString *identifier = nil;
if (self.segmentedControl.selectedSegmentIndex == 0) {
identifier = #"Cell1";
} else {
identifier = #"Cell2";
}
PatternViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
//configure cell
return cell;
}
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.
I have a UICollectionView, with custom UICollectionViewCell.
Every cell has a UITextView inside.
The problem: the UICollectionView is very slow, also in the simulator.
-(void)viewDidLoad
{
[self.collectionView registerClass:[AgendaCollectionCell class]
forCellWithReuseIdentifier:agendaCellIdentifier];
}
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
AgendaCollectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:agendaCellIdentifier forIndexPath:indexPath];
cell.delegate = self;
cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
[cell setCurrentDateAtIndex:([indexPath row]) date:currentMonth events:events];
// Return the cell
return cell;
}
I checked the profiler
Every cell makes date-related computations.
As you can see, the loadNibNamed takes too much time to load. Also the UITextView takes too much.
I searched a lot of question here and used some of their answers.(I also cached all instances of NSCalendar). I do not understand why it takes about 435 ms to load. The UICollectionView has 40 cell (it contains the days of a month).
Should I abandon the use of UICollectionView and cast to a custom view by using drawRect?
EDIT
I think that a good point is that suggested in the answer: load the cell by using UNib and not registerClass. I can see a very big performance boost: from 400ms to just 98ms!
Try putting
UINib * nib = [UINib nibWithNibName:#"YourNibName" bundle:[NSBundle mainBundle]];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:#"MyCell"];
into your viewDidLoad and then never create the cells yourself (in the
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForIndexPath:(NSIndexPath *)indexPath;
implementation always call
UICollectionViewCell * cell = [collectionView dequeueCell...]
This way, I think, the collection view will only load the nib once (in your viewDidLoad method and then create copies of it when needed.
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.
I've put a UICollectionView in the header of my table, but when I test it all I see is a black rectangle where my collection should be. What do I have to do to be able to see it? I did some research and found a method called viewForHeaderInSection, but I haven't found any explanation for it so I don't even know if that is what I need or what to do with it.
An additional question would be where do I put the related methods for the collection? (a new file?)
If it's important, this is on an IPad screen.
in your CellForRowAtIndexPath, add something like this.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* CellIdentifier = #"Cell";
UITableViewCell* cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
LiteratureScrollViewController* cv = [self.storyboard instantiateViewControllerWithIdentifier:#"collectionViewID"];
[cell.contentView addSubview:cv.view];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
[cv didMoveToParentViewController:self];
return cell;
}
I have had the same issue...
Select the actual collection view inside of your view in Storyboard. Check the background color. If you change it to "Clear Color" you just might see your collection view! While testing, to see your "item", select it, and set it's color to white, or something other than the view's background color.
In your UICollectionView Class do something like the method below to see which item was selected and then you can do whatever you want with selected object.
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
[self performSelector:#selector(singleTapOnCell:) withObject:indexPath];
}