UICollectionView slow scrolling - creating cells - objective-c

I am looking into collection view working on a project. My scrolling is ver slow for some reason, I think it's because I am doing a lot of processing in my cellForitemAtindex delegate method. Should I have UICollectionView create cells all at once rather then as it's scrolling? Or should can I cache the cells in some array on my own and then load from there as the user is scrolling? These are the only 2 I can think of, is there something else I can do? Thank you for your help.

inside cell for item at index path you need to get a cell like this
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"cellID" forIndexPath:indexPath];
instead of making it from scratch. If you are using a custom subclass for the cell register it with the collection view by calling registerClass:forCellWithReuseIdentifier:\
You are not in charge of allocating, initializing or caching the reusable cells, the collection view does it for you.

Related

Updating UITableView within UICollectionViewCell

I have a UICollectionViewCell containing some buttons, label and a UITableView. This table view varies in number of rows and content. The UICollectionViewCell is the table views data source and delegate.
UICollectionViewController forces me to use [collectionView dequeueReusableCellWithReuseIdentifier:#"CellID" forIndexPath:indexPath].
When scrolling through the UICollectionView the UITableView within the UICollectionViewCell doesn't update its content.
Calling [tableview reloadData] doesn't affect the number of rows.
Calling UICollectionViews reloadItemsAtIndexPaths:(NSArray *)indexPaths seems to be no good choice for performance.
Does anybody know a more clever way to update the table view inside the collection view cell instead of reusing previous cells' table views?
Have you set the delegate properly? If reloaddata is not updating the number of rows, there might be a problem with the delegate settings.

UITableViewCell prototype reuse between two UITableViews in the same view controller

Is it safe to deque UITableViewCell prototype from one table and use them in another?
When I want to display the UITableViewCell in the other UITableView I am simply dequeueReusableCellWithIdentifier a reusable cell from the table where the prototype type cells are specified. That is, not the UITableView they will be displayed in.
It seems to work fine and I haven't noticed any errors in the logs but I am concerned it might cause weird issues as I have not seen it done before.
Should I simply implement this using a separate nib for each cell? Or is this approach fine, bad practice or dangerous?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (self.prototypesTableView == tableView) {
cell = [self.prototypesTableView dequeueReusableCellWithIdentifier:cellType];
}
else if (self.otherTableView == tableView) {
cell = [self.otherTableView dequeueReusableCellWithIdentifier:cellType] ?: [self.prototypesTableView dequeueReusableCellWithIdentifier:cellType];
}
}
I'm pretty certain that each table view in memory has it's own queue of table view cells.
And when the table view (and view that hosts it) disappears, all the objects associated with it are released (assuming ARC here). Having one view with two tables shouldn't matter: each table has their own collection of cells to dequeue.
And in my own code, I frequently reuse the same custom "UITableViewCell" from one table to the next. To register a custom UITableView cell (which would be the only object in a XIB file), I do:
UINib * nib = [UINib nibWithNibName: #"SomeVeryCustomCell" bundle: nil];
if(nib)
{
[myTableView registerNib: nib forCellReuseIdentifier:#"SomeVeryCustomCell"];
}
This code is now running in production and I have seen no ill affects caused by dequeueing reusable cells from one table and using them in another. To ensure correct reuse I always dequeue from the "otherTableView" and if no UITableCell is available dequeue from the "prototypesTableView".
Although I implemented it like this for the sake expediency I would suggest it is better practice to implement it in the manner suggested by Michael, as it provides greater ability to share cells between view controllers.

JSON, cellForRowAtIndexPath bug

Struggling to find where fault is with my code. On first view load, everything works and loads fine as it should, but when i revisit that view, it seems that the first two cells are empty. I logged the dictionary (dict) in viewWillAppear: and it logs the data fine, so error has to be in cellForRow method. Take a look at my method, and see where i'm going wrong, the third cell populate third piece of data, so i'm totally stumped, but the first two cells are completely blank, no data.
http://pastebin.com/Va84MG5g
First of all, why are you doing all of that insane UITableViewCell customization inside of your tableView:cellForRowAtIndexPath: method? Create a custom UITableViewCell subclass and do the set up there.
In the class's initWithStyle: method, add all of your subviews with a frame of CGRectZero, because at initialization, the table view cell doesn't know how big it is. You can set text alignments, colors, etc. here as well. Then, in layoutSubviews, go ahead and set all the frames. Override prepareForReuse and set things like your UIImageViews to nil. This will help with performance for reused cells.
As for why you're not seeing your data in your first two cells, my initial thought is that it has something to do with the way you're setting up your cells for reuse. You're asking your tableView to dequeue a regular UITableViewCell and only creating all of these subviews if the returned cell is nil. So what happens when it returns a UITableViewCell? You skip the part where you alloc/init all these subviews, and so you're basically adding nothing to the cell. I feel if you create a custom subclass and ask your UITableView to dequeue that instead, you'll get the result you're looking for.
NOTE: If you're targeting at least iOS 5, you can create your UITableViewCell's layout in a nib and register the nib with the table view. Doing so will guarantee that you always get a dequeued cell, and you never have to do your if (cell == nil) check. If you're targeting iOS 6, you can register a UITableViewCell subclass.

Unload specific UITableViewCells

Is there a way to unload/release a UITableViewCell such that the containing UITableView calls cellForRowAtIndexPath: when it is needed again?
I understand that this is exactly what UITableView does by default, but only once the cells are outside the tableview frame. My custom view uses UITableView in such a way that its frame == content size.
If there is no way to unload specific cells, I'll have to think of a different approach.
The method [UITableView reloadRowsAtIndexPaths:withRowAnimation:] allows you to tell the table view to reload one or more cells. This will reload the specified cell(s) if they are on screen and presumably do nothing if they aren't currently on screen. Sounds like what you want though your question is not entirely clear to me.

How do i add UITableView in the UITableView cell?

I Have one tableview(First) in that i want another tableview(Second) in the cell of first tableView.
In short i want each cell contains one more tableview.
So help me out with this problem.
Thanks in advance.
Although I think the below method is better this tutorial shows you how to create a tableView inside of another tableView http://iosstuff.wordpress.com/2011/06/29/adding-a-uitableview-inside-a-uitableviewcell/
My Solution:
That approach is bound to run into serious problems, so I suggest scrapping it. If you have nested table views (or scroll views, more generally) then the scrolling behavior of the views will be erratic. A better solution is to use variable height table view cells: you just create the cell view to hold all the multiple choice options you need, and implement
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
in your table view delegate to supply the heights of the cells.