UITableView: how to make it not recycle cell? - objective-c

Is there a way to make table view not recycle UITableViewCell so after all cells are loaded, it won't ask for cells(ie tableView:cellForRow...)?
I know I can put the table view in a scroll view and make the table view to have the same size as the scroll view, so all cells will be loaded, but some of my cells have variable sizes, then I need to update the scroll view's content size after the cells' sizes are changed.
Is there any other way to do this?
update:
Sorry for the misleading, actually I mean how to make it not REMOVE cells once created, so if there are ten cells, and there won't be any cell returned by dequeueReusableCell and after ten tableView:cellForRow: it won't call it again.
Simply not use reusable identifier will make it create new cell every time as needed, even the cell at position 1 has been created but then reused for position 2.

Set the reuseIdentifier to nil.
This is much better than using a different identifier for each cell, as the table can now dispose unneeded cells quickly. If they have some identifier set, there's no way to tell if you will ever reuse them.
So you don't have to miss the reuse part completely, just for the cells you don't want to. If the new cell contains the same subviews (maybe just layout and configured differently) - it might still be better to reuse.

Just don't use a cellIdentifier, or use a different identifier for each cell.

just dont use - (id)dequeueReusableCellWithIdentifier:(NSString *)identifier
in the cellForRowAtIndexPath method and create a new cell everytime.
Other way is to give a different cell Identifier for each cell you create.
Now, If you can elaborate on why you dont want the tableview to recycle its cells (which is one of the powerful feature of tableview), may be you can find out other ways to achieve the same thing with reusing the cells..!!
Hope it helps..:)

Related

UITableViewCell Height Calculation and delegation?

I know this question had been asked hundreds of times before, but it's never really been solved (Or at least the way I'd like it to be). I have a rather complex UITableViewCell setup. The cell.backgroundView is loaded from a UIView subclass which uses a fair bit of CoreGraphics and CoreText. The code is rife with CTFramesetterSuggestFrameSizeWithConstraints, so I'm relectant to duplicate the class in the heightForRowAtIndexPath method.
I think I can solve this by creating an NSMutableDictionary with the indexPath as the key and the height as the value. But then I'm faced with the problem of heightForRowAtIndexPath being called first. I believe I can solve this problem by guessing the height of the cell and then once the cell's UIView subclass has finished rendering, use delegation to set the cell's height.
But this leaves me with the problem, how the hell do I delegate this? And, how to I prevent scrolling from being extremely choppy? as the cells will be created and resized in a split second.
In the past, I've used a dummy cell. I have a separate method -fillInCell:forRowAtIndexPath: which puts data into the cell. That way I can fill out the dummy cell in -tableView:heightForRowAtIndexPath: and the real cell in -tableView:cellForRowAtIndexPath:.
If this does not work for you then there are other options.
The first thing that comes to mind is create real cells in -tableView:heightForRowAtIndexPath: instead of -tableView:cellForRowAtIndexPath:. You can store completed cells in a mutable dictionary. -tableView:cellForRowAtIndexPath: will simply pull the completed cell from the dictionary. You should also detect when scrolling has stopped so you can empty your dictionary (just because -tableView:heightForRowAtIndexPath: was called doesn't mean -tableView:cellForRowAtIndexPath: will get call for the same indexPath).
Hope that helps.

UITableViewCell Accessory Views Duplicate In Defferent Sections When Scroll The UitableView

This question make me troubled for a long time, I want to implement defferent accessory views on different cells in my tableview.
And my tableview have multiple sections, But they duplicate onto other cells in my other sections that I have not implemented when I scroll up and down the UITableView. I know someone said "It should be Use different identifiers when you assign dequeueReusableCellWithIdentifier: for each cell in cellForRowAtIndexPath: method before,
But I don't know how to implement programmatically in detail, Anybody can write a sample code in detail help me to understand?
Thank you very much!!!!!
Its all well and good to use different accessory views. But you have to keep in mind that if you are recycling cells, then you first try to recycle, if none available you create a cell, THEN you need to set the appropriate accessory view for the particular cell you are going to return. Who knows what the old one was for a recycled cell...

UITableView dequeueReusableCellWithIdentifier unique or not?

This may sound a newbie question, however I'm new to iOS dev,
I want to understand when I should use UNIQUE identifier for the cells and when not for
- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier
Actually in lots of places I've met code snippets where identifier was not unique.
But in my practice I've used unique identifier in order to keep the order of the UITableViewCells, otherwise the order was mixed when I've scrolled UITableView up and down.
So please help me to understand the concept of reusable cells, shan't each cell have unique identifier?
Thanks in advance,
You should use different identifiers only for different types of cell. If your table view had different classes of cell this may be your problem, or you have added subviews to a cell that vary in their presence from cell to cell.
When using an identifier, think about it in terms of your cell could contain the data of any previously rendered cell data, so you need to ensure your code overwrites that data, in the most simple case cell.textLabel.text.
I believe I've got the answer to my question. Thanks to Aaron's question.
I always try to initialize each cell only once in the same view (of course if it's not being edited in that view). I do this to enhance the performance and smooth the scrolling of the table view.
The difference is - now I know how it works. If I get it right, cell identifier makes the cells to stay unique and this way table does something like caching that information and then putting it to the right place (because of unique identifiers).
Thank you guys!
Always try to initialize each cell only once in the same view . I do this to enhance the performance and smooth the scrolling of the table view. The difference is - now I know how it works. If I get it right, cell identifier makes the cells to stay unique and this way table does something like caching that information and then putting it to the right place.

How to remove cells that can be reused in UITableView (MonoTouch)

We have a scenario where we reuse the same UITableView to display different sets of records from the database as a user selects an item in a different UITableView (similar in concept to a splitviewcontroller, but all in the same view).
When the user selects a different area to view, we fetch the appropriate records from the database, update the Source with the new set of records, and call ReloadData.
The problem is that some of the cells in the UITableView still exist and are reused when switching between lists, resulting in invalid or overlapped data for various rows.
The question I have is: is there a method whereby we can tell the UITableView to discard all existing cells including those queued for reuse? I would have expected ReloadData to perform this task, but it does not.
Update with additional clarification:
Each cell in our table is composed of a variable number of subviews (we are trying to mimic a grid control). When the user selects a different list in the left-hand navigation, there is no guarantee that the subview positions (columns) in the newly selected list will overlap with those in the previous list. This is why we are looking for a method to remove the queued cells.
Since this is a situation that others may find themselves in, I will post the solution that we used, but am still interested in more "native" ways of doing this.
Here is how we solved the issue:
When the set of records being displayed is changed, we update the UITableView with a unique identifier for the current cell configuration (i.e. which list of data is the user currently viewing).
We then created a custom version of UITableViewCell and record the unique list identifier in the cell when it is created.
When we dequeue a reusable cell, we compare the view's current unique identifier with the unique identifier stored in the cell and, if they don't match, we discard the cell and create a new one.
Hopefully this will help someone down the road.
ReloadData does not clear the re-use queue. It simply triggers the callbacks to re-read the data which reloads the rows. As each cell get's loaded, if you're getting it out the re-use queue it will still be used. That's good even if the table view is re-used because the cell types are the same type especially since you use the CellIdentifier to ensure that.
But, it's kind of odd that you're overlapping data. When you get a cell out of the re-use queue, how are you putting the data in it? Are you painting the data directly on the cell? Are you adding subViews with the data (causing multiple sets of overlapped data)? Typically, a cell contains subviews like text labels and the data is set on them so there's no scenario where data gets overlapped - the subviews of cell just has their data updated ...
Your GetCell method needs to ensure that a dequeued cell is fully configured with the new data that it is going to display.
A common mistake is assuming that just dequeuing the cell for display will give you a fresh cell that you can use.
If you have done any customization with your cell, like adding views, modifies its properties (images, disclosure indicators, background colors) you must make sure in the GetCell method that is reusing a cell that every single one of those properties is properly set before returning the cell.

Accessing a specific cell in an NSTableView

I have an NSTableView with some cells that where the value of enabled is set through bindings. I want to be able to change the colour of the cells depending on whether the cell is enabled or not. Previously I have done this through the NSTAbleView delegate method tableView: willDisplayCell: forTableColumn: row: which up until now worked fine. I've had to switch off the table delegate though and so I need to find another way to do it. I suspect it's a problem with an obvious answer, but how do I access each cell in the table? I can get the number of rows and columns in the table, and I can cycle trough them, I'm just not sure what method to call to get the cell in column i, row j.
Generally speaking, you shouldn't be cycling through the rows and columns. Your code should be able to do the right thing, given any row or column.
One way to do it is to write your own cell class and implement the appropriate drawing and highlighting methods that you'll find in the NSCell documentation. You'd implement
– drawWithFrame:inView: and probably -highlight:withFrame:inView:
Yet another way is to subclass NSTableView, and override -preparedCellAtColumn:row: to do whatever manipulation of the cell you want just before it's drawn.
The easiest way to do what you want though, is to just use the delegate method as you were before. Why don't you want to do it that way?
Assuming you don't want to color an entire column, the easiest way is tableView:willDisplayCell:forTableColumn:row:, since there is only one cell per column (the view uses the same cell for that column in every row).
Why did you get rid of your delegate?