Как переместить UIScrollView в активное UITextField, пока устройство не работает?

#objective-c #uiscrollview #uitextfield #cgrect

#objective-c #uiscrollview #uitextfield #cgrect

Вопрос:

Хорошо, итак, я в тупике. Я использую уведомления с клавиатуры и UIScrollView для прокрутки до текущего активного текстового поля при его нажатии. Он работает точно так, как ожидалось, как в книжной, так и в альбомной ориентации, ЗА исключением случаев, когда устройство находится в горизонтальном положении.

В альбомной ориентации, если устройство удерживается в воздухе, оно прокручивается, как и ожидалось, но когда устройство лежит на столе и нажимается текстовое поле, просмотр прокручивается полностью за пределами экрана.

Что вызывает это?

Я тестирую на iPad Mini и iPhone 5 с использованием 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;
}
  

Ответ №1:

Ваш расчет размера клавиатуры намного сложнее, чем должен быть. Пусть API сделает всю работу за вас:

 - (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];
    }
}