UITableView is getting interaction when changing rows with animation - iphone

I have a tableview on a nib file with the interaction setting turned off. I'm animating a section change like this:
[myTableView beginUpdates];
[myTableView deleteSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES];
[myTableView insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:YES];
[myTableView endUpdates];
The problem is that, when I do this, the rows become selectable. How do I keep the interaction disabled while keeping the animation?

use this
self.tableView.userInteractionEnabled=NO;

Related

UITableview reload SectionHeader but not cells in section

I have a tableview where I want to reload (and change the height of) just the sectionHeader but not the cells inside this section. The reason I want to do this is because I use the fade animation on the header, like so:
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:UITableViewRowAnimationFade];
But at the same time I am adding a cell in that section with
[self.tableView insertRowsAtIndexPaths:
#[[NSIndexPath indexPathForRow:0 inSection:0]]
withRowAnimation:UITableViewRowAnimationRight];
I'd like to be able to keep the UITableViewRowAnimationRight for the cell that is being added, but when I reload the Section, the fade animation gets applied to the whole section. Is there any way to just reload the sectionHeader, and not the cells in the section?
Just create 2 separate brackets of
[tableView beginUpdates];
[tableView endUpdates];
for the two insertions / changes.

Animate the newly added row in the table

Is it possible to get IndexPath currently inserting new row into a table. The table data is loaded through the Core Data. The datas are sorted through the sections.
I would like to make a new added row to the table to be animated as shown in the following picture link.
http://i45.tinypic.com/2ykjj7n.png
You can use following method:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
The code is tested, and will definitely work for you...
What about this? Is this what you want to gather? I am not sure.
[yourTableView beginUpdates];
[yourTableView moveRowAtIndex:firstStateIndex toIndex:endStateIndex];
[yourTableView endUpdates];
Of course you have to insert the specific row at first so that you can move it afterwards. The animation could happen like this.
[tblMainView beginUpdates];
[tblMainView reloadRowsAtIndexPaths:<#(NSArray *)#> withRowAnimation:UITableViewRowAnimationLeft];
[tblMainView endUpdates];

Scroll to last UITableViewCell using scrollToRowAtIndexPath:atScrollPosition:animated using NSFetchedResultsControllerDelegate methods

I am adding a new item to the bottom of a UITableView and after inserting the item, I want the UITableView to scroll to the very bottom to display the newly inserted item. New items are saved to Core Data and the UITableView is automatically updated using NSFetchedResultsController.
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
switch (type) {
case NSFetchedResultsChangeInsert:
NSLog(#"*** controllerDidChangeObject - NSFetchedResultsChangeInsert");
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
//THIS IS THE CODE THAT DOESN'T WORK
[self.tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
break;
....
}
This leads to an out of bounds error, I can't seem to make it work. I can scroll to the second to last comment by adjusting the row of the index path, but I can't get to the very last item.
Basically, I'm adding a comment to a table of comments and after a comment is added, I want the table to scroll to the most recent comment.
You need to call endUpdates so that the tableView can calculate its new sections and rows. A simple case would look like this:
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:insertedIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
[self.tableView scrollToRowAtIndexPath:insertedIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
As you use NSFetchedResultsController, it is a bit more complicated, as the calls do beginUpdates, insertRowsAtIndexPaths:withRowAnimation:, and endUpdates are typically in different delegate methods. What you could do then is
add a property insertedIndexPath to store the inserted index path
after the -insertRowsAtIndexPaths:withRowAnimation: call in -controller:didChangeObject:atIndexPath:, add
self.insertedIndexPath = insertedIndexPath;
after [self.tableView endUpdates] in -controllerDidChangeContent:, add
if (self.insertedIndexPath) {
[self.tableView scrollToRowAtIndexPath:self.insertedIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
self.insertedIndexPath = nil;
}
See if this helps...
[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
[self.tableView scrollToRowAtIndexPath:newIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];

Make UITableView go to top line

I sometimes reload table data and I need to redraw the table so that I see the data from the first row again. What I do now is the following:
NSIndexPath *ip = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView selectRowAtIndexPath:ip animated:NO scrollPosition:UITableViewScrollPositionTop ];
[self.tableView deselectRowAtIndexPath:ip animated:NO];
This is not ideal because there is an annoying flash when row 0 is selected and immediately deselected.
How can I fix this?
You can use UITableView's scrollToRowAtIndexPath:atScrollPosition:animated: method.
[tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
If you have a header that is in view by default, and want to compensate if the action is called when the list is in motion use:
[tableview setContentOffset:CGPointMake(0.0, 0.0) animated:NO];
Short, simple, effective.
You can set contentoffset of tableview to (0.,0.).

How to refresh a UITableViewController or NSFetchedResultsController?

I have a little problem with my UITableViewController or NSFetchedResultsController. I am not sure which is the problem soure but I guess its the UITableViewController.
As I said I use a NSFetchedResultsController to fill my data into a UITableViewController. The data is sorted by date and is also displayed in sections by date-year, e.g. May 2010/June 2010/ and so on. This is displayed as the section header.
Now when I add new data, it automatically uses the current date as default, but if I want to use a date, that is currently not in the section list, e.g. April 2010 (currently May and June in the list), then this is not displayed correctly. Only when I quit the app and start it again it will show the new section headers and everything is fine.
So I somehow need to be able to refresh my list or update it. By just adding it to the context and changing it does not seem to update it.
Again, I am not sure what I need to update, if it is my NSFetchedResultsController object or the UITableViewController.
UPDATE #1:
I just figured that there is an exception in this method :
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
// The fetch controller has sent all current change notifications, so tell the table view to process all updates.
[self.tableView endUpdates];
}
This is where I move the data :
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
switch(type)
{
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
// [self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
// Reloading the section inserts a new row and ensures that titles are updated appropriately.
[tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
This method is pretty much taken from the CoreDataBooks example from Apple. And this is the error :
Serious application error. An
exception was caught from the delegate
of NSFetchedResultsController during a
call to -controllerDidChangeContent:.
*** -[NSMutableArray removeObjectAtIndex:]: index 1 beyond
bounds [0 .. 0] with userInfo (null)
And after that, the edit mode (where the delete button appears) does not work anymore.
Thanks.
Ok, looks like I found a solution, I just skip these
[self.tableView beginUpdates];
[self.tableView endUpdates];
and always do this.
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView reloadData];
}
I will obviously give this some more logic, since the problem only occures when I want to move my data in a section that does not exist before. Until someone can give me a real solution, I will go with this one.
Adopting the fix by Apple in iPhoneCoreDataRecipes in version 1.2, the proper thing to do is to replace
// Reloading the section inserts a new row and ensures that titles are updated appropriately.
[tableView reloadSections:[NSIndexSet indexSetWithIndex:newIndexPath.section] withRowAnimation:UITableViewRowAnimationFade];
with
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
(FileMerge is your friend!)
Note, there's another fix in version 1.2 that prevents erratic crashing when creating new entries. I had reported this and it was fixed within two weeks. I encourage you to file bug reports with Apple. They're far more responsive than you think, and you can expect to get the best possible fix.
You need to implement the controller:didChangeSection:atIndex:forChangeType: delegate methods. In it, send insertSections:withRowAnimation:, deleteSections:withRowAnimation:, and reloadSections:withRowAnimation: messages to your table view depending on the reported change type.