I'm using a CollectionView to display data. When the user presses a certain button, I am refreshing the CollectionViewCell to reflect the changes like this:
[self.collectionView reloadItemsAtIndexPaths:[NSArray arrayWithObject:indexPath]];
This works fine to reload the cell, except it doesn't reload it's footer view. I implemented the following method
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"FOOTER CALLED");
This doesn't get called when I reload the cell.
Eveything works if I reload the whole collection view with [self.collectionview reloadData], but this is not efficient.
How to make sure the Footer of my UICollectionViewCell at indexPath gets refreshed also?
You have to invalidate the layout or reload the section.
Invalidating the layout.
[[_collectionView collectionViewLayout] invalidateLayout]
Reloading the section. Use reloadSections: to update 1 or more sections in the UICollectionView.
[self.collectionView reloadSections:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 3)]];
Related
I am creating a tableView which has collectionView inside.
what I did :
1. Created a table view inside a controller.
2. created a custom tableViewCell with collectionView inside of that and providing it with tag
3. Created a custom collectionViewcell.
Now i made controller the delegate and datasource for both collectionView and tableView.
Now tableView should have multiple tableViewcells and each tableViewCell has CollectionView
One tableViewCell has one section.
Problem :-
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
self.arrayModel = self.SlotsArray[indexPath.section];
}
But here is a catch : lets say my screen size shows two tableViewcell, then all methods of tableCells are called first and then all methods of collectionView are called instead i want that after 1st section of tableViewcell is created , it should call collectionView methods and create it. then go to tableView method make 2nd section and then create its collectionView.
Is there away to do this.
Somewhere i read on net thet i will have to subclass CollectionView and add a property index and then while setting viewcontroller as delegate and datasource , set index also.
But i have created CollectionView By nib and adding it to the tableCell class by "TAG"
self.imageCollectionView = [self.contentView viewWithTag:2511];
Can you tell how can i achieve this?
In your case, you should have one table view, having cells. Each cell will have a collection view inside it.
Number of table view cells will equal to the count of your data-source. As we all know, table view cell will be created one by one and assign each cell a data source which will be used to fill your collection view (which is inside each cell).
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CategoryCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifierCategory forIndexPath:indexPath];
NSArray *arrVideos = [parentArray objectAtIndex:indexPath.row];
[cell setCollectionData:arrVideos];
return cell;
}
Now, inside that table view cell class, implement setCollectionData method to fill its collection view:
- (void)setCollectionData:(NSArray *)collectionData
{
self.arrCollectionData = collectionData;
[self.yourCollectioView reloadData];
}
Now, each collection cell would be feed from this array:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
VideoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:kCellIdentifierVideo forIndexPath:indexPath];
NSDictionary *_video = [self.arrCollectionData objectAtIndex:[indexPath row]];
// Use this dictionary
[cell.lblVideoTitle setText:_video.title];
––––––––––
––––––––––
return cell;
}
Refer following image:
Hope it helps you !!!
You can take a look on this, surely it will help you to implement horizontal scrolling collection view inside uitableviewcell.
https://github.com/ThornTechPublic/HorizontalScrollingCollectionView/blob/master/GithubImages/videoGrid.gif
https://github.com/agusso/ASOXScrollTableViewCell
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.
I have a tableview in a scrollview in a popover. When the view is presented, the bottom cell in tableview is not visible to the user. If I select all of the cells then deselect the fist cell, the out of view cell is deselected too. Has anyone come across this behaviour before? If so, how to approach it?
Now your job is to find all the visible cells in the tableview and then apply select/deselect to it.
UITableView *tableView = self.tableView;
// Or however you get your table view
NSArray *paths = [tableView indexPathsForVisibleRows];
// For getting the cells themselves
NSMutableSet *visibleCells = [[NSMutableSet alloc] init];
for (NSIndexPath *path in paths)
{
[visibleCells addObject:[tableView cellForRowAtIndexPath:path]];
}
// Now visibleCells contains all of the cells you care about.
-(void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:
(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath {
//stuff
//as last line:
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
For that matter, deselectRowAtIndexPath can be called from anywhere at any time you want the row to be deselected.
[self.myTableView deselectRowAtIndexPath:[self.myTableView
indexPathForSelectedRow] animated: YES];
If you are using dequeueReusableCellWithIdentifier: change your cellForRowAtIndexPath: to use dequeueReusableCellWithIdentifier:forIndexPath:
In a UITableView cells get reused. That means it only produces as many as absolutely needed. As soon as a new one is coming onto the screen, the last one is "recycled" instead of initialising a whole new instance.
This makes your application run faster. It also means that you have to undo any changes you made, when recycling.
Selection status is one of them. The UITableView should manage this automatically for you, if it is dequeued with the relevant indexPath. If not, it wouldn't know whether that specific cell should be selected.
In Objective C UITableVIew how to retain scroll position after calling reload
While selecting a cell I call reload function of the UITableView but after reload I want the scroll to maintain its position (i.e, Position where the cell was tapped)
You can use reloadRowsAtIndexPaths:withRowAnimation: instead of reloadData.
You could do something like this.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}
Also if you want to scroll to some particular position, you can use this.
[tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionNone animated:YES];
Two lines and you get the desired result:
NSArray *indexPaths = tableView.indexPathsForVisibleRows;
[tableView reloadRowsAtIndexPaths:indexPathswithRowAnimation:UITableViewRowAnimationNone];'
I have creating a excel view using collection view. Earlier I was facing an issue while scrolling the collection view listed at :
https://stackoverflow.com/questions/27036224/scrolling-disturbs-layout-of-collectionview
I fixed that issue with the after seeing Shivam's reply in:
Collection View,with custom layouts, cells misbehave on scrolling
-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
NSString *cellID = [NSString stringWithFormat:#"%#%d", #"cCell",indexPath.row];
[myCollectionView registerClass: [CustomCell class] forCellWithReuseIdentifier:cellID];
CustomCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:cellID forIndexPath:indexPath];
[self configureCell:cell forIndexPath:indexPath];
return cell;
}
-(void)configureCell:(CustomCell*)cell forIndexPath:(NSIndexPath*)indexPath{
// configuration code
}
I don't know whether it is correct or not, but's its working.But now I am stuck in another problem related to reload of collection view.
Problem::: I have textfield in the cells for which I have implemented textFieldDidEndEditing delegate. I have also provided Next Button which provides proxy navigation to all cells in collection view as desired by me. In the clicked method of next button, I am saving the currentIndexpath, reloading the collection view, getting the next cell using saved index path, getting the textfield and making it as first responder. But next textfield never becomes first responder. I debugged the issue and find that after reload I am not able to retrieve the cell. If I remove the reload line then everything works fine.
NSIndexPath *reqIndexPath = [NSIndexPath indexPathForItem:colId inSection:currentSection];
CustomCell *cell = (CustomCell*)[self.collectionView cellForItemAtIndexPath:reqIndexPath];
I get this resolved by :
[self.collectionView reloadData];
[self.collectionView layoutIfNeeded];
Thanks to Lukewar reply in
Reloading a UICollectionView using reloadData method returns immediately before reloading data