Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have attempted Apple's example here:

http://developer.apple.com/library/ios/#documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

However, it doesn't seem to work so I'm clearly missing something along the way, just can't figure out what.

I have a ViewController.h containing:

@interface PreferencesViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, defaultLocationChoice, UITextFieldDelegate, UIScrollViewDelegate>

@property (nonatomic, retain) NSString *defaultLocation;
@property (nonatomic, retain) NSString *defaultTestType;
@property (nonatomic, assign) id <defaultLocationChoice> locationDelegate;
@property (nonatomic, weak) IBOutlet UITableView *tableView;
@property (nonatomic, strong) IBOutlet UITextField *locationnameTextField;
@property (nonatomic, strong) IBOutlet UITextField *locationaddressTextField;
@property (strong, nonatomic) IBOutlet UITableView *scrollView;
@property (nonatomic, strong) IBOutlet UITextField *activeField;

There are all Synthesized in the .m file.

I have the Apple code has follows in ViewController.m

- (void)viewDidLoad
{
    NSUserDefaults *sharedPref = [NSUserDefaults standardUserDefaults];
    defaultLocation =[sharedPref stringForKey:@"defaultLocation"];
    defaultTestType =[sharedPref stringForKey:@"defaultTestType"];

    [self registerForKeyboardNotifications];


    self.navigationItem.title = @"Preferences";

    [super viewDidLoad];

}

- (void)registerForKeyboardNotifications

{

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillBeHidden:)
 name:UIKeyboardWillHideNotification object:nil];

}

// Called when the UIKeyboardDidShowNotification is sent.

- (void)keyboardWasShown:(NSNotification*)aNotification

{
    NSDictionary* info = [aNotification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;

    // If active text field is hidden by keyboard, scroll it so it's visible

    // Your application might not need or want this behavior.

    CGRect aRect = self.view.frame;
    aRect.size.height -= kbSize.height;

    if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {

        CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-kbSize.height);

        [scrollView setContentOffset:scrollPoint animated:YES];
    } 
}



// Called when the UIKeyboardWillHideNotification is sent

- (void)keyboardWillBeHidden:(NSNotification*)aNotification

{
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    scrollView.contentInset = contentInsets;
    scrollView.scrollIndicatorInsets = contentInsets;
}

- (void)textFieldDidBeginEditing:(UITextField *)textField

{
    activeField = textField;
}



- (void)textFieldDidEndEditing:(UITextField *)textField

{
    activeField = nil;
}

The Cells containing the TextFields are dealt with in CellForRowAtIndexPath as below (full code not shown):

  case 2:
            switch (indexPath.row) {
                case 0:

                    prefCell.textLabel.text = @"";
                    prefCell.accessoryType = UITableViewCellAccessoryNone;
                    prefCell.highlighted = NO;
                    locationnameTextField.frame = CGRectMake(5, 12, 300, 30);
                    locationnameTextField.font = [UIFont systemFontOfSize:13.0f];
                    locationnameTextField.placeholder = @"Enter location name i.e. New York, NY";
                    locationnameTextField.delegate = self;
                    locationnameTextField.returnKeyType = UIReturnKeyDone;
                    [prefCell.contentView addSubview:locationnameTextField];

                    break;
                case 1:
                    prefCell.textLabel.text = @"";
                    prefCell.accessoryType = UITableViewCellAccessoryNone;

                    locationaddressTextField.frame = CGRectMake(5, 12, 300, 30);
                     locationaddressTextField.font = [UIFont systemFontOfSize:13.0f];
                    locationaddressTextField.placeholder = @"Enter location address i.e. mcs.newyork.com";
                    locationaddressTextField.clearsOnBeginEditing = YES;
                    locationaddressTextField.delegate = self;
                    locationaddressTextField.returnKeyType = UIReturnKeyDone;

                    [prefCell.contentView addSubview:locationaddressTextField];

                    break;
            }

On running the app the keyboard pops up and nothing happens.

Apples example is for a View so the only code I changed above was self.view.frame to self.tableView.frame to no effect.

I added the ScrollView as an addition as I didn't have one. My other ViewControllers with embedded TableView don't require a ScrollView to scroll.

The hierarchy is as follows:

enter image description here

Any help would be great, thanks

share|improve this question

2 Answers

You have to do as following:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
 [yourTextField resignFirstResponder];
}
share|improve this answer
this removes the keyboard if the TextField is selected and I try scrolling, which isn't what I need. I require the active TextField to move above the keyboard when it appears. – Dan James Palmer Mar 11 at 13:21

I was scratching my head with the same problem when I noticed the superview of textfield. If I'm right, you have the textfield inside a cell of tableview.

Now, in your keyboardWasShown: method, you are checking whether active text field is hidden under the keyboard like this:

if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
    CGPoint scrollPoint = CGPointMake(0.0, activeField.frame.origin.y-kbSize.height);
    [scrollView setContentOffset:scrollPoint animated:YES];
} 

The if condition will never be true in your case. Since the superview of active text field is a cell, the activeField.frame.origin will return a point in reference to a UITableViewCell, not in reference to your UIView.

Hence, what you need to do is check if the cell containing the active text field is hidden under the keyboard, something like this:

CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, cellForActiveField.frame.origin) ) {
    CGPoint scrollPoint = CGPointMake(0.0, cellForActiveField.frame.origin.y-kbSize.height);
    [scrollView setContentOffset:scrollPoint animated:YES];
} 

To find the cell containing active text field, you need to set the tag property of textfield in tableView:cellForIndexPath: method and then check for the tag in textFieldDidBeginEditing: method.

For more details, refer this question as well.

Hope this helps.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.