Reputation: 440
Okay, so I am stumped on this one. I'm using keyboard notifications and a UIScrollView to scroll to the current active text field when it is tapped. It works exactly as expected in both portrait and landscape EXCEPT when the device lays flat.
In Landscape orientation, if the device is held in the air it scrolls as expected, but when the device is laid flat on a table and a text field is tapped the view scrolls completely off screen.
What causes this?
I am testing on an iPad Mini and iPhone 5 using iOS7.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Register for keyboard notifications
[self registerForKeyboardNotifications];
// keep track of scrollview insets for later
scollViewIndicatorInsets = self.scrollView.scrollIndicatorInsets;
}
- (IBAction)editingEnded:(id)sender {
[sender resignFirstResponder];
}
- (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;
if (UIInterfaceOrientationIsLandscape([UIDevice currentDevice].orientation)) {
kbSize = CGSizeMake(kbSize.height, kbSize.width);
}
UIEdgeInsets contentInsets = UIEdgeInsetsMake(65.0, 0.0, kbSize.height, 0.0);
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
[self.scrollView scrollRectToVisible:activeField.frame animated:YES];
}
}
// Called when the UIKeyboardWillHideNotification is sent
- (void)keyboardWillBeHidden:(NSNotification*)aNotification
{
// UIEdgeInsets contentInsets = UIEdgeInsetsZero;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(65.0, 0.0, 0.0, 0.0);
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
activeField = textField;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
activeField = nil;
}
Upvotes: 0
Views: 308
Reputation: 318794
Your calculation of the keyboard size is much more complicated than it should be. Let the API do the work for you:
- (void)keyboardWasShown:(NSNotification*)aNotification
{
NSDictionary* info = [aNotification userInfo];
CGRect kbFrame = [info[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
// Convert the keyboard frame from the window to the scrollview
kbFrame = [self.scrollView convertRect:kbFrame fromView:nil];
CGSize kbSize = kbFrame.size;
UIEdgeInsets contentInsets = UIEdgeInsetsMake(65.0, 0.0, kbSize.height, 0.0);
self.scrollView.contentInset = contentInsets;
self.scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
CGRect aRect = self.view.frame;
aRect.size.height -= kbSize.height;
if (!CGRectContainsPoint(aRect, activeField.frame.origin) ) {
[self.scrollView scrollRectToVisible:activeField.frame animated:YES];
}
}
Upvotes: 1