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
Related
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?
i have the indexPath number... i need to remove the cell accessory from that cell based on the number in the variable i have?
NSInteger *removeAccessoryFrom = 3;
[studentTableView cellForRowAtIndexPath:removeAccessoryFrom].accessoryType = UITableViewCellAccessoryNone;
It doesn't work like that. You need to reload the table data (either for the whole table or for just this row) and, inside cellForRowAtIndexPath, set the accessoryType to UITableViewCellAccessoryNone conditionally. In other words, you keep a list, or have some other way of knowing, at every moment, and for the entire table, exactly what cells get exactly what accessory. That way, any time cellForRowAtIndexPath is called, you can configure this cell for this index path correctly.
I'm trying to programmatically select cells in a UICollection view. I'm new to Obj-C and I'm not quite sure how to use the selectItemAtIndexPath property. I can grab an array of the images the user has previously selected. It is just an array of numbers corresponding to named images. But I'm not sure how to use that information with selectItemAtIndexPath.
I've looked for examples of someone using
- (void)selectItemAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated scrollPosition:(UICollectionViewScrollPosition)scrollPosition
But I'm not sure how to use it with my UICollectionView so I can have the right cells selected when the view loads and thus be highlighted. I have multiple selection on.
You should call selectItemAtIndexPath: for each cell you want to highlight, like so:
[self.collectionView selectItemAtIndexPath:path animated:NO scrollPosition:UICollectionViewScrollPositionNone]
Note that for one item (and one only!) you probably want to set the animated property to YES and provide a scroll position (one item only because otherwise you're going to be making a lot of needless animation calls).
You'll first need to get the index paths of the cells you want to select. The index path consists of two numbers: the section the cell is in and the row number (or order, if your collection view doesn't have rows) of the cell inside that section.
If you store the index paths of the cells the user has selected in an array then you can just iterate through. Otherwise you'll need to find the index path out, using a UICollectionView method such as indexPathForCell.
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?
I am using a custom tableviewcell in one of my view's. I have decided to add a UISwitch to this cell to enable the user to delete multiple row's at once.
Normally when the user selects a row and taps my delete button I have a UIAlert pop up for confirmation and after that the alert clickedButtonAtIndex method handles the outcome. In that method I get the indexpath ( [self.myTableView indexPathForSelectedRow] ) and delete (or not) accordingly.
So basically as the title states instead of using the indexPath to fall into my delete statement, I need to check to see if self.myTableView.myCell.mySwitch.on is TRUE. Can anyone point me in the right direction for doing this? I will need to iterate through all rows in the tableview and for each row where the state is on it needs to be removed.
Thanks.
you should iterate through your cells using a nested loop ( or a single loop if you have only one section) and cellForRowAtIndexPath:.if you see a cell's switch.on = TRUE save it's indexPath in an array by calling indexPathForCell:. after you're done iterating through your cells, call deleteRowsAtIndexPaths:withRowAnimation: with the array previously created.