Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

terryah

macrumors newbie
Original poster
Feb 20, 2013
3
0
Hi Everyone,

I am having a problem that I cannot seem to fix. I have been looking all over the internet to find a solution but cannot find one.

I have a UITableView that I am using as data editor. In each cell I have 3 UITextFields and when you click on the Next/Previous buttons I would like it to scroll through the UITextFields and if you are pressing Next from the last UITextField in the cell the focus should move to the next cell.

All of this works fine if I do it just that way. The problem is that my UITableView is not completely displayed on the screen so if you click Next to a cell that is not on the screen then click Previous to the original cell, any changes you made are lost.

I therefore added code to the textFieldDidEndEditing function to copy the data to the data element in the NSArray. Now my data is not lost when the above takes place. The problem with this is now my Next/Previous function does not work as the UITextField is no longer able to become first responder.

I have run some tests and it comes down to having an assignment statement in either the same block with the resignFirstResponder and becomeFirstResponder code or in the textFieldDidEndEditing function. Below is the working and non working code.

I am really hoping someone can help me with this.

Working Code
Code:
- (void) nextField:(id)sender
{
    NSLog(@"Next Field");
    UITableViewCell *cellTmp = [[self tableView] cellForRowAtIndexPath:self.selectedIndexPath];
    GradingSchemeCell1 *cell = (GradingSchemeCell1 *)cellTmp;
    GradingScheme *selectedObject = [self.fetchedResultsController objectAtIndexPath:cell.indexPath];
    NSLog(@"Letter Grade: %@, GPA: %@",[selectedObject letterGrade], cell.cellField1.text);

    int selectedSection = self.selectedIndexPath.section;

    if (cell == nil)
    {
        return;
    }
    if ([cell.cellField1 isFirstResponder])
    {
        [cell.cellField1 resignFirstResponder];
        [cell.minGrade becomeFirstResponder];
        [self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    }
   ...
}
Broken Code:
Code:
- (void) nextField:(id)sender
{
    NSLog(@"Next Field");
    UITableViewCell *cellTmp = [[self tableView] cellForRowAtIndexPath:self.selectedIndexPath];
    GradingSchemeCell1 *cell = (GradingSchemeCell1 *)cellTmp;
    GradingScheme *selectedObject = [self.fetchedResultsController objectAtIndexPath:cell.indexPath];
    NSLog(@"Letter Grade: %@, GPA: %@",[selectedObject letterGrade], cell.cellField1.text);

    int selectedSection = self.selectedIndexPath.section;

    if (cell == nil)
    {
        return;
    }
    if ([cell.cellField1 isFirstResponder])
    {
        [cell.cellField1 resignFirstResponder];
        [COLOR="Red"]selectedObject.gPA = [[NSDecimalNumber alloc] initWithString:cell.cellField1.text];[/COLOR]
        [cell.minGrade becomeFirstResponder];
        [self.tableView scrollToRowAtIndexPath:[self.tableView indexPathForCell:cell] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
    }
   ...
}
As you can see above. The only code that is different is the assignment statement after the resignFirstResponder.

Any help is very appreciated.

Thanks and Regards,
Terry
 
Last edited by a moderator:

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
I usually save the text on every keystroke in my data model when working with textFields in table views.

Do you have any of the "should" delegate methods implemented and do they return NO in any cases?
 

terryah

macrumors newbie
Original poster
Feb 20, 2013
3
0
Thanks for the reply.

The only "should" delegate method I use is the textFieldShouldBeginEditing and that one is setup to always return true.

What delegate do you use to save on each keystroke?

Regards,
Terry
 

PhoneyDeveloper

macrumors 68040
Sep 2, 2008
3,114
93
UITextField is a UIControl subclass and it sends an action message for UIControlEventValueChanged. You just have to register for that message either in IB or code. It also posts a UITextFieldTextDidChangeNotification and your code can register for that notification.
 

terryah

macrumors newbie
Original poster
Feb 20, 2013
3
0
Hi,

I finally figure out what the problem with my code was. For the UITableViewController I use CoreDataTableViewController as my parent class. In that class is the following function:
Code:
- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
	   atIndexPath:(NSIndexPath *)indexPath
	 forChangeType:(NSFetchedResultsChangeType)type
	  newIndexPath:(NSIndexPath *)newIndexPath
{		
    if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
    {
        switch(type)
        {
            case NSFetchedResultsChangeInsert:
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
                
            case NSFetchedResultsChangeDelete:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
                
            case NSFetchedResultsChangeUpdate:
                [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
                
            case NSFetchedResultsChangeMove:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }
}

The assignment statement I use was updating the data in the FetchedResultsController this function was called in order to ensure the TableView was refreshed with the changed data, which was causing the problem I was having. As soon as I commented out the above function everything started working perfectly.

Thanks,
Terry
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.