Custom Tableview getting crash in iPhone5(iOS7) - objective-c

In my app i am using two table one for filter the data and second for results data. I am using the following line to scroll the tableview at selected index position,
self.indexPaths = [NSIndexPath indexPathForRow:0 inSection:indexPath.row];
[tableview scrollToRowAtIndexPath:self.indexPaths atScrollPosition:UITableViewScrollPositionTop animated:YES];
[tableview reloadData];
but my app is getting crash in only in iPhone5(iOS7) and working fine in all devices even iPhone5(iOS6).
Why does this crash only on iPhone5(iOS7)?
Crashing log is: Terminating app due to uncaught exception 'NSInvalidArgumentException'

You pass integer (0) for index path. You should pass NSIndexPath instead, try:
NSIndexPath *ip = [NSIndexPath indexPathForRow:0 inSection:0];
[tableview scrollToRowAtIndexPath:ip atScrollPosition:UITableViewScrollPositionTop animated:NO];

NSIndexPath is an object so you can't pass 0.
Try [NSIndexPath indexPathWithIndex:0]

self.indexPaths = [NSIndexPath indexPathForRow:0 inSection:indexPath.row];
the RHS returns the indexpath corresponding to a row and section.
in the above code,
you are passing indexpath.row to inSection parameter. This may be wrong.Assume, you have 1 section and 5 rows. when indexpath.row = 4(for eg), there wont be a section corresponding to 4 and hence self.indexPaths becomes nil since the system would try to look for row 4 in section 4, but section 4 doesnt exist!!
Consequently, when you pass nil to below line, it says nsinvalidargument exception.
tableview scrollToRowAtIndexPath:self.indexPaths atScrollPosition:UITableViewScrollPositionTop animated:YES];

Related

Dynamically loading UITableView with new rows

I have searched SO and have yet to come to a definitive answer.
I have an app similar to Facebook and Instagram, where once you get to the bottom of the UITableView it calls a web service and loads another 25 rows of data.
The problem I facing is that on loading the new 25 pieces, I am calling reloadData and this causes unpleasant UI flashing.
What's the proper way of dynamically adding the new data to the UITableView as they scroll without the flashing (aka not calling reloadData?
After you add the new row items to your data source you need to use [tableView beginUpdates]; and [tableView endUpdates]; not reloadData.
NSMutableArray *indexPathsToAdd = [NSMutableArray new];
for (Object *object in currentObjects)
{
if (![newObjects containsObject:object]) {
int row = [currentObjects indexOfObject:object];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
[indexPathsToAdd addObject:indexPath];
}
}
[tableView beginUpdates];
[tableView insertRowsAtIndexPaths:indexPathsToAdd withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView endUpdates];

Inserting new item in UITableView leads to invalid number of sections

I'm losing my mind here. Relevant code:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return [[self.currentWorkout movements] count];
}
And...
- (void)addMovement:(Movement *)movement{
[self.currentWorkout.movements insertObject:movement atIndex:0];
[self.table beginUpdates];
NSIndexPath *path = [NSIndexPath indexPathForRow:0 inSection:0];
[self.table insertRowsAtIndexPaths:#[path] withRowAnimation:UITableViewRowAnimationTop];
[self.table endUpdates];
}
I have confirmed that insertObject:atIndex: is adding the object; the count of currentWorkout increases by one.
Error: 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (8) must be equal to the number of sections contained in the table view before the update (7), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).'
Solved: using wrong method to insert sections.
- (void)addMovement:(Movement *)movement{
[self.currentWorkout.movements insertObject:movement atIndex:0];
NSLog(#"%d",(int)[self numberOfSectionsInTableView:self.table]);
[self.table beginUpdates];
[self.table insertSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationTop];
[self.table endUpdates];
}
Removing the [self.table beginUpdates]; method call is important because otherwise the table will think it has the number of rows it would get after adding the object before that object is actually added.

Can't programmatically delete row from UITableView

I'm trying to implement a custom deletion process for my app, as my costumer doesn'y want the red circle provided by table view edition mode. I have added a deletion button for every row, with row number in its tag property. Once user clicks deletion button, it fires following method:
-(IBAction)deleteRow:(id)sender{
UIButton *tempButton = (UIButton*)sender;
[self updateTotals];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:tempButton.tag inSection:0];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView reloadData];
[sharedCompra removeItem:tempButton.tag];
tempButton=nil;
}
And I allways get this error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (3) must be equal to the number of rows contained in that section before the update (3), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
So I don't know if I'm missing something in this piece of code.
Many thanks.
You're trying to delete a row whereas your data source still reflects the original state (i. e. that before the deletion). You have to update the data source first, it's only then that you can issue a deletion from the table viev. You also don't need to set the button to nil, nor do you need to call - reloadData on the table view:
- (void)deleteRow:(id)sender
{
UIButton *tempButton = sender;
[self updateTotals];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:tempButton.tag inSection:0];
[sharedCompra removeItem:tempButton.tag];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
(One thing you should do, however, is paying attention to how you format your code.)
Call [sharedCompra removeItem:tempButton.tag]; before [tableView deleteRowsAtIndexPaths... and [tableView reloadData]
The problem is that when you call deleteRowsAtIndexPath: it is calling numberOfRowsInSection which returns the same count from your model.
Also reloadData call is not needed here.
When deleting and adding rows, you need to call beginUpdates, here how it should look.
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
and you don't need to call reloadData, or it will cancel the animation of the deleteRows, and insertRows methods. But you do need to reset the data, so if you're using an NSMutableArray, you need to remove the object first, so item at index 0, then you can delete row 0 in table. the number of rows needs to match the number of objects in that array when it ends deleting or it will also crash.

UITableViewController canceling Edit mode animation when calling [table reloadData] inside (void)setEditing

I'm having a little problem:
i made my setEditing method:
- (void)setEditing:(BOOL)editing animated:(BOOL)animate {
[super setEditing:editing animated:animate];
[mainTableView reloadData];
}
i'm using the reloadData to call: cellForRowAtIndexPath, and then, if the table is in edit mode, i'll change the appearance of my cell (hiding some labels, for example);
The problem is when i call [mainTableView reloadData] the Edit animation (the red circle slides from left to right and my cell slides to the right) doesn't exist. If don't call it, everything works ok, but i can't customize my cell, since cellForRowAtIndexPath is not called again.
Any suggestion to make it work ??
Thanks!
Maybe you will try to update your table with [tableView beginUpdates] and [tableView endUpdates]? Do you need to reload all the cells or only some of them?
EDIT: Here's the code for reloading all the cells:
[tableView beginUpdates];
NSMutableArray *updatedPaths = [NSMutableArray array];
for (NSNumber *row in yourArray) {
NSIndexPath *updatedPath = [NSIndexPath indexPathForRow:[row intValue] inSection:0];
[updatedPaths addObject:updatedPath];
}
[tableView reloadRowsAtIndexPaths:updatedPaths withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
yourArray is NSArray instance where you store your cell.textLabel values or something like that...

-[UITableView scrollToRowAtIndexPath:] scrolls, but goes back to 1st row

I have a grouped table view with textfields in the tableview. For the keyboard to not hide the textfields, in the textFieldShouldBeginEditing, I am calling the scrollToRowAtIndexPath method and setting the scroll position of the row being edited to the top of the tableview.
The scrolling does happen, but as soon as the keyboard appears (ie as soon as the textFieldShouldBeginEditing returns YES), the table scrolls back to its original position and displays the first row of the first section on top. I am not calling reloadTable after making a call to scrollToRowAtIndexPath.
The problem occurs only for row 4 and 5 (bdate and zip) password2 works as expected.
This is the code I am using to scroll to a particular row
if(textField == password2){
indPath = [NSIndexPath indexPathForRow:3 inSection:0];
[self.tableView scrollToRowAtIndexPath:indPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
return YES;
}
else if(textField == bdate){
indPath = [NSIndexPath indexPathForRow:4 inSection:0];
[self.tableView scrollToRowAtIndexPath:indPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
return YES;
}
else if(textField == zip){
indPath = [NSIndexPath indexPathForRow:5 inSection:0];
[self.tableView scrollToRowAtIndexPath:indPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
return YES;
}
Can someone please tell me what could be going wrong? Any insight would help.
Thanks
I suspect what is going on is that the table view is rubber banding back, just like a webview in Safari does when you run pass its bounds. The most likely reason for this is that when you pop up the keyboard it is on top of the table view, but the table view has not physically contracted, thus all the UITableViewCells fit within the partially obscured UITableView, and when some of them scroll off it rubber bands so they all are within it.
In order to test this try reducing the size of the list view so that you can see the whole thing when the keyboard is displayed, if the bug goes away you want to write code that dynamically changes the size as the keyboard animates in and out.
//For iOS 7
[self.TableView reloadData];
NSIndexPath *indexPat = [NSIndexPath indexPathForRow:1 inSection:1];
[self.TableView scrollToRowAtIndexPath:indexPat atScrollPosition:UITableViewScrollPositionTop animated:YES];