tags:

views:

9209

answers:

4

I have an application that works some what similar to how iPhone's Contact application works. When we add a new Contact user is directed to a view only screen with Contact information. If we select "All Contacts" from the navigation bar, user is navigated to list of all contacts where the recently added contact is in view.

We can move the view to a particular row using:

    [itemsTableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionBottom];

... but it's not working. I'm calling this right after calling:

    [tableView reloadData];

I think i'm not suppose to call selectRowAtIndexPath:animated:scrollPosition method here. But if not here, then where?

Is there any delegate method that gets called after the following method:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

Thanks, Mustafa

A: 

Do you have enough dummy contacts added to test the scrolling? It seems that only when your tableView is of a certain size the iPhone finds the inputus to scroll.

This is the code that works for me in my project. I use a previous button and therefore I scroll the tableview a little bit further down that it usually would go with UITABLEVIEWSCROLLPOSITION. (my previous button won't work if it can't "see" the previous cell.

Ignore some of the custom method calls.

- (void)textFieldDidBeginEditing:(UITextField *)textField {

    //Show the navButtons
    [self navButtonAnimation];


    DetailsStandardCell *cell = (DetailsStandardCell *)textField.superview.superview.superview;

    self.parentController.lastCell = cell;


    //Code to scroll the tableview to the previous indexpath so the previous button will work. NOTE previous button only works if its target table cell is visible.
    NSUInteger row = cell.cellPath.row;
    NSUInteger section = cell.cellPath.section;

    NSIndexPath *previousIndexPath = nil;


    if (cell.cellPath.row == 0 && cell.cellPath.section != 0) //take selection back to last row of previous section
    {
    NSUInteger previousIndex[] = {section -1, ([[self.sections objectForKey:[NSNumber numberWithInt:section - 1]]count] -1)};
    previousIndexPath = [[NSIndexPath alloc] initWithIndexes:previousIndex length:2];   
    }
    else if (cell.cellPath.row != 0 && cell.cellPath.section != 0)
    {
     NSUInteger previousIndex[] = {section, row - 1};
     previousIndexPath = [[NSIndexPath alloc] initWithIndexes:previousIndex length:2];  

    }


    [self.theTableView scrollToRowAtIndexPath: cell.cellPath.section == 0 ? cell.cellPath : previousIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];

}
Dan Morgan
A: 

The problem i'm having is with "Add New Cell". E.g. Contacts application. When a new Contact is added using a new View, and user come back to "All Contacts" list, the table is redrawn. Now, where should i put the code to move the scroller? I have a notification method in parent view controller (Controller that handles Contact list display) which is responsible for adding new cell in the table view. When the notification methods finishes, i have to call [tableView reloadData] inorder to show the newly added cell in the table. Here's my code:

- (void)addContactNotification:(NSNotification *)notification {
NSLog(@"Add Contact notification message received.");
Contact *newContact = (Contact *)[notification object];

NSLog(@"Adding received item in My Contacts list.");
[myContacts addContact:newContact];

NSLog(@"Reloading Contact table's data.");
[tableView reloadData];

/*
// Find Index Path for newly created item
NSLog(@"Getting newly added Contact's identity information and opening it's detail view.");
NSInteger row = [myContacts findItemWithID:[newContact identity]];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];

// Scroll the view to show the recently added Contact
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionBottom];

// Open Detail View
NSLog(@"Opening Detail View for newly added Contact.");
[self tableView:tableView didSelectRowAtIndexPath:indexPath];
 */
}

I want the code commented above to work for me. Right now, the code adds new cell to the table, but it does not scroll to the correct position.

Any help/pointer will be great. Thanks.

Mustafa
+5  A: 

I think I've got a similar app: A list of item., tap '+' -> new screen, come back and see the updated list, scrolled to show the added item at the bottom.

In summary, I put reloadData in viewWillAppear:animated: and scrollToRowAtIndexPath:... in viewDidAppear:animated:.

// Note: Member variables dataHasChanged and scrollToLast have been
// set to YES somewhere else, e.g. when tapping 'Save' in the new-item view.

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    if (dataHasChanged) {
        self.dataHasChanged = NO;
        [[self tableView] reloadData];
    } else {
        self.scrollToLast = NO; // No reload -> no need to scroll!
    }
}

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    if (scrollToLast) {
        NSIndexPath *scrollIndexPath = [NSIndexPath indexPathForRow:([dataController count] - 1) inSection:0];
        [[self tableView] scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
    }
}

I hope this helps. If you add something in the middle of the list, you could easily scroll to that position instead.

squelart
A: 

I guess the only thing i was missing was that i was doing this exact thing right after the [tableView reloadData] in my method rather than in viewDidAppear.

Thanks squelart.

Mustafa