views:

547

answers:

2

I'm using an tableView with custom cells. When I want to display another view using the pushViewController function of the navigationController I loop through the textfields and call resignFirstResponder on them. But resignFirstResponder does only work when the textfields are being displayed so I scroll first to the top of the page. This is the code:

NSIndexPath *topIndexPath;
topIndexPath = [[NSIndexPath indexPathWithIndex:0] indexPathByAddingIndex:0];
[self.tableView scrollToRowAtIndexPath:topIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];

[[self textFieldForRow:0] resignFirstResponder];
[[self textFieldForRow:1] resignFirstResponder];
[[self textFieldForRow:2] resignFirstResponder];
[[self textFieldForRow:3] resignFirstResponder];

This works, but after this my tableView has some weird problem with its origin. I tried to set it's superviews origin to 0, but that doesn't help.

Here is a screenshot of the problem: link

As you can see, my tableview is too large and the scrollbar is stuck in the middle of the view when reaching the bottom.

Sorry for my english, I hope that you can understand me,

Thanks in advance!

Hans

A: 

I would fix your other problem. I imagine when you say you can't call "resignFirstResponder" when the other textFields are on screen, you mean that there is a crash?

If so, it is because of screen cells don't exist and therefore the textfields are gone as well. They are recycled (so they can be dequeued for new cells).

The easy solution is to only call resignFirstResponder only on textFields that ARE on screen.

What you are doing now seems a little hacky.

Corey Floyd
The problem is when my tableView is at the bottom, no textField is displayed, but the keyboard is still displayed. Is there a way of resigning the keyboard when the textfield is about to leave the screen?
HansPinckaers
+1  A: 

It was actually quite simple. Just put your resignFirstResponder in -viewWillDisappear

edit: this is better and less hacky, I added this to my class, and it worked:

edit 2: seems that your app will be rejected when using the previous code. Here is a updated public api version:

- (void)viewWillDisappear:(BOOL)animated
{
    [self.view findAndResignFirstResponder];
}

And:

@implementation UIView (FindAndResignFirstResponder)
- (BOOL)findAndResignFirstResponder
{
    if (self.isFirstResponder) {
        [self resignFirstResponder];
        return YES;     
    }
    for (UIView *subView in self.subviews) {
        if ([subView findAndResignFirstResponder])
            return YES;
    }
    return NO;
}
@end

(source: http://stackoverflow.com/questions/1823317)

HansPinckaers
Someone's app has be reject from the app store because of using this method. It's in this thread if you're interested. http://stackoverflow.com/questions/1823317/how-do-i-legally-get-the-current-first-responder-on-the-screen-on-an-iphone
Hua-Ying
Thank you so much:) changed the code.
HansPinckaers