Reload one Row without animation (reloadRowsAtIndexPaths). Picture inside - objective-c

In my Example i 've got 2 Sections with 1 Row at the Start. It someone clicks on the first row of a section i insert all other rows of this section:
[tableView insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationTop];
This works fine, but i need to update the Background of the first row. This works too, but i need to relayout the first row. I have tried setNeedsDisplay and setNeedsLayout, but it don't worked. A reloadDate shows the right background, but it destroys the sliding effect.
I know that i can update a Row with one of this:
[tableView reloadRowsAtIndexPaths:indexArrayReload withRowAnimation:UITableViewRowAnimationFade];
[tableView reloadRowsAtIndexPaths:indexArrayReload withRowAnimation:UITableViewRowAnimationNone];
But they change the hight of the Row temporary. I need a real fading effect or a reload without animation.
Here is the Picture of the Situation:
Edit: I 've made a video:
This shows the Problem!

This is the solution:
[tableView beginUpdates];
...
[tableView endUpdates];
I fond it in another thread.

Related

NSOutlineView numberOfRows doesn't increase after reloadData

I want to calculate the size of a cell that I've just added to an NSOutlineView. To do that, I add it to my data source, and then call reloadData on the NSOutlineView. For some reason, however, I can't examine the cell after reloadData for any but the very first row. The code looks like this:
[m_dataSource add:...]; // first add item to my data source
[m_outlineView reloadData];
int nRows = (int) [m_outlineView numberOfRows];
NSCell *cell = [m_outlineView preparedCellAtColumn:0 row:nRows-1];
NSSize size = [cell cellSize];
For some reason, nRows is always 1 here, no matter how many rows I add. Thus, I can only ever query the size of the first cell in the very first row.
The behaviour I see might be related to the fact that the very first row is an expandable row and all other rows are children of the very first row. However, I have checked that
- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item;
correctly returns YES for the item. Everything also appears correctly in the NSOutlineView. It's just that numberOfRows doesn't seem to get updated even though I call reloadData just before it.
Any ideas what's wrong here?

iOS static table view not so static

I'm developing a static grouped table view with storyboard. Anyway, sometimes I'd like not to display some of the rows. As long as the rows I want to hide are in the middle, I can set the height of that specific cell to 0 and the trick works :)
Anyway, when I want to hide the last cell of a group (I'm using a grouped table view), my trick obviously does not work. That's because the previous cell won't get the round corners typical of the last cell. Is there another trick that can help me with this issue?
I solved my problem implementing the method
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
even if I'm using a static table view.
The proper way to remove a cell from a table view after it has been rendered is to use the UITableView method called deleteRowsAtIndexPaths:withRowAnimation: . Here is a code sample:
[tableView deleteRowsAtIndexPaths:#[myCellIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

Excess UITableView cells

I have a custom UITableViewCell that seems to appear multiple times on my table before I even start scrolling. It seems dequeueReusableCellWithIdentifier isn't working properly. Here's my cell:
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[MyCustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
... setup ...
}
When I call reloadRowsAtIndexPaths: on my tableView, for some reason it doesn't dequeue that cell and it recreates the new one. Then when I scroll back up and then down again, sometimes my first cell dequeues, sometimes the second cell dequeues. MyCustomCell is basically a textfield so depending on which one dequeues, the text has different data each time.
Is there something more I should be doing in my custom cell? Thanks in advance.
You mention reloadRowsAtIndexPaths: in your question, but the method is actually reloadRowsAtIndexPaths:withRowAnimation:. The fact that the reload can be animated matters. For example, to animate UITableViewRowAnimationLeft, the table view needs to slide out an old cell while sliding in a new cell. Both the old and new cells are on screen simultaneously, so the table view can't just use the same UITableViewCell object for both. That's why “it doesn't dequeue that cell and it recreates the new one”. It needs a new one because the old one is still visible.
You need to make sure that when you receive a tableView:cellForRowAtIndexPath: message, you fully initialize the cell (whether dequeued or newly created) to show the data for the requested row, and only the data for the requested row.
Also, you can't keep your own mapping from the row's indexPath to the cell, because (during animations) there may be two cells for the same row. Instead, if at any time you need to get the cell that is currently showing the data for a row, you need to ask the table view for the cell by sending it a cellForRowAtIndexPath: message.
From the code you show, it looks as if you only set up your cell's content when a new one is created. Since there's no way of knowing which cell you'll be given from the cache, you need to configure the cell whether it's new or one that's being re-used.

UITableViewCell's disappear after insertion/deletion

I have a few UITableView's in my project, and sometimes I need to swap cells between them. Cells are complex enough and it's take a lot of time to re-create them each time I move them from one table to another, so I create its once, keep in array and pick up necessary cells  in cellForRowAtIndexPath Moving cells between tables looks something like this:
NSIndexPath* pathForMovedCell = [firstTableView indexPathForCell:movedCell];
[firstTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:pathForMovedCell] withRowAnimation:UITableViewRowAnimationFade];
//There is some delay for show animation and switch between view controllers
[secondTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:pathForMovedCell] withRowAnimation:UITableViewRowAnimationFade];
This code works pretty good, but sometimes (always, if delay less then 0,33 seconds) cell is not drawn on secondTableView. It normally inserted, and will be drawn if scroll them from visible area and return back. I think it's happens if inserting occurs before deletion animation ends. If I made short delay, cells disappears often, and I don't want to leave big time reserve, because it looks like lags, so I want to solve this problem correctly. I tried to add [cell setNeedsDisplay] before returning cell from cellForRowAtIndexPath, but it doesn't work.
Any suggestion?

reloadTable after animated row deletion

I have a table view with cells that can be deleted. When a cell is deleted, I would like to display a deletion animation such as UITableViewRowAnimationFade. The problem is that my table view's cells have alternating background colors, so I need to -reloadData after the animation completes to fix the colors of all cells below the deleted cell.
So, incase you haven't read this far, I need a way to run some code after a table view animation is complete. I am currently using performSelector:withObject:afterDelay: and hardcoding an approximation of the animation delay. This method works, but there must be a better way to do it:
NSIndexPath * path = [listTable indexPathForCell:deletingCell];
NSArray * indexPaths = [NSArray arrayWithObject:path];
[listTable deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
[listTable performSelector:#selector(reloadData) withObject:nil afterDelay:0.35];
In this case I am assuming that UITableViewRowAnimationFade will take less than 0.35 seconds to complete.
You could also use NSTimer with the same delay (although unneeded, -performSelector:withObject:afterDelay: works fine).
Another option would be to loop through the cells after deletingCell (path) and redraw them, or add the index paths to an array and call reloadRowsAtIndexPaths:withRowAnimation: as shown below. Then you could also use the UITableViewRowAnimationFade
- (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation