2013-04-16 1 views
10

Я понимаю, что существует много подобных решений, таких как TPKeyboardAvoiding, Apple's famous solution и различные предложения, связанные с использованием UIScrollView. В моем случае мне нужно изменить размер представления, чтобы разместить клавиатуру, а не прокручивать или перемещать ее. This solution подходит ближе всего к тому, чего я пытаюсь достичь, поэтому это была моя основа. Однако у меня проблема, в которой все работает в ландшафтном режиме. Мой метод, который изменяет размер представления при появлении этой клавиатуры:Изменение размера представления при появлении клавиатуры (iOS)

- (void)keyboardWillShow:(NSNotification *)note { 
    NSDictionary *userInfo = note.userInfo; 
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 
    UIViewAnimationCurve curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue]; 

    CGRect keyboardFrame = [[self textField].superview convertRect:[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue] fromView:nil]; 
    CGRect statusBarFrame = [[self textField].superview convertRect:[UIApplication sharedApplication].statusBarFrame fromView:nil]; 

    CGRect bounds = [self textField].superview.bounds;  
    CGRect newFrame = CGRectMake(0.0, 0.0, bounds.size.width, keyboardFrame.origin.y + statusBarFrame.size.height); 
    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{ 
     [self textField].superview.frame = newFrame; 
    } completion:nil]; 
} 

Это прекрасно работает в портретном режиме.

enter image description here

Однако в ландшафтном режиме, вид изменяет размеры слева направо или справа налево в зависимости от того, в каком направлении было повернуто устройство, а не снизу вверх.

enter image description here

Очевидно, что что-то не так с тем, как я использую координаты, а некоторые системы отсчета не то, что я думаю, что это когда в ландшафтном режиме, но у меня чертовски времени как решить проблему. Я пробовал конвертировать всевозможные вещи с помощью -convertRect: но ничто из того, что я пытаюсь, не приводит меня нигде.

Я действительно надеюсь, что кто-то, кто менее смущен всеми этими прямоугольниками и как они меняются, когда изменения ориентации могут определить, что я делаю неправильно, и что мне нужно сделать, чтобы это исправить. Для справки, у меня есть created a project, где показан самый простой случай, который воспроизводит проблему, которую я испытываю.

+0

Вы хотите повернуть iPan, когда клавиатура видна? –

+0

В идеале, да, поскольку я уверен, что некоторые пользователи сделают это. Но я думаю, что если я смогу заставить это решение работать (я добавляю метод, когда клавиатура скрыта, чтобы снова изменить размер резервной копии), которая будет работать автоматически. Я верю, что когда устройство поворачивается с показанной на клавиатуре, iOS последовательно отправляет уведомления о клавиатуреWillHide и keyboardWillShow. – bkocik

+0

Спасибо за код анимации, очень удобно. – phatmann

ответ

26

Я не рекомендую изменять размер корневого представления для вашего контроллера вида, вы можете создать contentView и добавить к виду контроллера вида. Вы можете изменить размер этого содержимогоView, как показано ниже (я не использую автоопределение):

- (void)keyboardWillShow:(NSNotification *)note { 
    NSDictionary *userInfo = note.userInfo; 
    NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 
    UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; 

    CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; 
    keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil]; 

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{ 
     self.contentView.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y); 
    } completion:nil]; 
} 

- (void)keyboardWillHide:(NSNotification *)note { 
    NSDictionary *userInfo = note.userInfo; 
    NSTimeInterval duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 
    UIViewAnimationCurve curve = [userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]; 

    CGRect keyboardFrameEnd = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; 
    keyboardFrameEnd = [self.view convertRect:keyboardFrameEnd fromView:nil]; 

    [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionBeginFromCurrentState | curve animations:^{ 
     self.contentView.frame = CGRectMake(0, 0, keyboardFrameEnd.size.width, keyboardFrameEnd.origin.y); 
    } completion:nil]; 
} 
+0

Большое вам спасибо! Изменяет ли размер моего корневого представления мою единственную проблему? (Кроме того, что я не скрываю себя как наблюдателя на dealloc и не имею кода для запуска при скрытии клавиатуры, у меня есть те, которые находятся в самом приложении.) – bkocik

+0

Теперь приложение очень просто, поэтому сложно говорить о каких-либо проблемах :). В будущих возможных проблемах вы всегда можете решить здесь. –

+0

Это спасло мне столько головной боли ... большое спасибо! –

-1

Попробуйте эти методы. Отредактируйте его в соответствии с вашими требованиями.

#define kOFFSET_FOR_KEYBOARD 280.0 

- (void)keyboardWillHide:(NSNotification *)notif { 
    [self setViewMoveUp:NO]; 
} 


- (void)keyboardWillShow:(NSNotification *)notif{ 
    [self setViewMoveUp:YES]; 
} 


- (void)textFieldDidBeginEditing:(UITextField *)textField { 
    stayup = YES; 
    [self setViewMoveUp:YES]; 
} 


- (void)textFieldDidEndEditing:(UITextField *)textField { 
    stayup = NO; 
    [self setViewMoveUp:NO]; 
} 

//method to move the view up/down whenever the keyboard is shown/dismissed 
-(void)setViewMoveUp:(BOOL)moveUp 
{ 
    [UIView beginAnimations:nil context:NULL]; 
    [UIView setAnimationDuration:0.3]; // if you want to slide up the view 
    [UIView setAnimationBeginsFromCurrentState:YES]; 

    CGRect rect = self.view.frame; 
    if (moveUp) 
    { 
     // 1. move the view's origin up so that the text field that will be hidden come above the keyboard 
     // 2. increase the size of the view so that the area behind the keyboard is covered up. 

     if (rect.origin.y == 0) { 
      rect.origin.y -= kOFFSET_FOR_KEYBOARD; 
      //rect.size.height += kOFFSET_FOR_KEYBOARD; 
     } 

    } 
    else 
    { 
     if (stayup == NO) { 
      rect.origin.y += kOFFSET_FOR_KEYBOARD; 
      //rect.size.height -= kOFFSET_FOR_KEYBOARD; 
     } 
    } 
    self.view.frame = rect; 
    [UIView commitAnimations]; 
} 
+0

Спасибо, но это перемещает представление - мне нужно изменить размер моего - и с помощью жестко закодированного значения; Я предпочитаю находить размер их клавиатуры во время выполнения для будущей проверки. – bkocik

1

я сделал это надеюсь, что этот код будет полезно для и.

- (void)viewWillAppear:(BOOL)animated 
{ 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(keyboardWillShow:) 
               name:UIKeyboardWillShowNotification 
               object:nil]; 

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

- (void)keyboardWillShow:(NSNotification*)notification 
{ 
    [self moveControls:notification up:YES]; 
} 

- (void)keyboardWillBeHidden:(NSNotification*)notification 
{ 
    [self moveControls:notification up:NO]; 
} 

- (void)moveControls:(NSNotification*)notification up:(BOOL)up 
{ 
    NSDictionary* userInfo = [notification userInfo]; 
    CGRect newFrame = [self getNewControlsFrame:userInfo up:up]; 

    [self animateControls:userInfo withFrame:newFrame]; 
} 

- (CGRect)getNewControlsFrame:(NSDictionary*)userInfo up:(BOOL)up 
{ 
    CGRect kbFrame = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; 
    kbFrame = [self.view convertRect:kbFrame fromView:nil]; 

    CGRect newFrame = self.view.frame; 
    newFrame.origin.y += kbFrame.size.height * (up ? -1 : 1); 

    return newFrame; 
} 

- (void)animateControls:(NSDictionary*)userInfo withFrame:(CGRect)newFrame 
{ 
    NSTimeInterval duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; 
    UIViewAnimationCurve animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue]; 

    [UIView animateWithDuration:duration 
          delay:0 
         options:animationOptionsWithCurve(animationCurve) 
        animations:^{ 
         self.view.frame = newFrame; 
        } 
        completion:^(BOOL finished){}]; 
} 

static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCurve curve) 
{ 
    return (UIViewAnimationOptions)curve << 16; 
} 
+0

Большое усилие, но ответ был дан ответ два года назад. Чтобы лучше использовать свои навыки, вы можете посмотреть список последних вопросов о своих тегах. http://stackoverflow.com/questions/tagged/iphone?sort=newest&pageSize=30 –

+0

Хорошо спасибо большое –

5

Ответ Виталия Б в быстром. Я получил представление под названием templateHeaderContentView, я создал функцию и настроил ее высоту. Вы используете свой собственный вид и соответственно изменяете высоту.

func keyboardWillShow(notification: NSNotification) { 
    keyboardShowOrHide(notification) 
} 

func keyboardWillHide(notification: NSNotification) { 
    keyboardShowOrHide(notification) 
} 

private func keyboardShowOrHide(notification: NSNotification) { 
    guard let userInfo = notification.userInfo else {return} 
    guard let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey]else { return } 
    guard let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] else { return } 
    guard let keyboardFrameEnd = userInfo[UIKeyboardFrameEndUserInfoKey] else { return } 

    let curveOption = UIViewAnimationOptions(rawValue: UInt(curve.integerValue << 16)) 
    let keyboardFrameEndRectFromView = view.convertRect(keyboardFrameEnd.CGRectValue, fromView: nil) 
    UIView.animateWithDuration(duration.doubleValue ?? 1.0, 
     delay: 0, 
     options: [curveOption, .BeginFromCurrentState], 
     animations: {() -> Void in 
      self.templateHeaderContentView.configureView(keyboardFrameEndRectFromView.origin.y) 
     }, completion: nil) 
} 
+0

Я использовал ответ Витайли, но подумайте о включении функции configureView для потомков;) – Greg