двигаться вверх UIToolbar - PullRequest
       30

двигаться вверх UIToolbar

9 голосов
/ 23 декабря 2009

У меня UIToolbar внизу моего обзора, и у меня есть UITextField на этой панели инструментов. Когда я начинаю редактировать это поле, оно скрывается за клавиатурой. Чтобы увидеть, что я напечатал, я хочу переместить панель инструментов вверх в момент представления клавиатуры (и затем переместить ее обратно вниз, когда я закончу редактирование).

Как мне переместить этот UIToolbar вверх / вниз?

Ответы [ 5 ]

13 голосов
/ 23 декабря 2009

добавьте ваш класс viewController в список наблюдателей UIKeyboardWillShowNotification / UIKeyboardWillHideNotification. затем вы можете переместить ваш вид, чтобы сделать текстовое представление видимым. Вы также можете получить параметры анимации из этих уведомлений, чтобы синхронизировать анимацию с параметрами анимации клавиатуры текущей версии ОС. этот код я использовал для подкачки

- (void) viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(liftMainViewWhenKeybordAppears:) name:UIKeyboardWillShowNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(returnMainViewToInitialposition:) name:UIKeyboardWillHideNotification object:nil];
}
- (void) viewWillDisappear:(BOOL)animated{
    [super viewWillDisappear:animated];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

в методах ниже я установил два метода для обработки уведомлений клавиатуры. и вот такие методы:

- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification{
    NSDictionary* userInfo = [aNotification userInfo];
    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardFrame;
    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
    [[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame];
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:animationDuration];
    [UIView setAnimationCurve:animationCurve];
    [self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
    [UIView commitAnimations];
}
- (void) returnMainViewToInitialposition:(NSNotification*)aNotification{
    NSDictionary* userInfo = [aNotification userInfo];
    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardFrame;
    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
    [[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame];
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:animationDuration];
    [UIView setAnimationCurve:animationCurve];
    [self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + keyboardFrame.size.height, self.view.frame.size.width, self.view.frame.size.height)];
    [UIView commitAnimations];
}
8 голосов
/ 11 марта 2010

Спасибо, что сработало! Вот небольшое улучшение:

- (void) liftMainViewWhenKeybordAppears:(NSNotification*)aNotification{
    [self scrollViewForKeyboard:aNotification up:YES];
}

- (void) returnMainViewToInitialposition:(NSNotification*)aNotification{
    [self scrollViewForKeyboard:aNotification up:NO];
}

- (void) scrollViewForKeyboard:(NSNotification*)aNotification up: (BOOL) up{
    NSDictionary* userInfo = [aNotification userInfo];

    // Get animation info from userInfo
    NSTimeInterval animationDuration;
    UIViewAnimationCurve animationCurve;
    CGRect keyboardFrame;
    [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
    [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
    [[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&keyboardFrame];

    // Animate up or down
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:animationDuration];
    [UIView setAnimationCurve:animationCurve];

    [self.view setFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y + (keyboardFrame.size.height * (up?-1:1)), self.view.frame.size.width, self.view.frame.size.height)];
    [UIView commitAnimations];
}
5 голосов
/ 05 октября 2013

Опираясь на ответы выше и используя удобный метод [UIView animateWithDuration ...]. Наблюдайте за тем, чтобы показать / скрыть уведомления клавиатуры и использовать эти обработчики.

- (void)keyboardWillShow:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    NSNumber *durationValue = info[UIKeyboardAnimationDurationUserInfoKey];
    NSNumber *curveValue = info[UIKeyboardAnimationCurveUserInfoKey];
    NSValue *endFrame = info[UIKeyboardFrameEndUserInfoKey];

    [UIView animateWithDuration:durationValue.doubleValue
                          delay:0
                        options:(curveValue.intValue << 16)
                     animations:^{
                         self.navigationController.toolbar.frame = CGRectMake(0,
                                                                              [endFrame CGRectValue].origin.y - self.navigationController.toolbar.bounds.size.height,
                                                                              self.navigationController.toolbar.bounds.size.width,
                                                                              self.navigationController.toolbar.bounds.size.height);
                     }
                     completion:nil];
}

- (void)keyboardWillHide:(NSNotification*)aNotification
{
    NSDictionary* info = [aNotification userInfo];
    NSNumber *durationValue = info[UIKeyboardAnimationDurationUserInfoKey];
    NSNumber *curveValue = info[UIKeyboardAnimationCurveUserInfoKey];

    [UIView animateWithDuration:durationValue.doubleValue
                          delay:0
                        options:(curveValue.intValue << 16)
                     animations:^{
                         self.navigationController.toolbar.frame = CGRectMake(0,
                                                                              self.view.bounds.size.height - self.navigationController.toolbar.bounds.size.height,
                                                                              self.navigationController.toolbar.bounds.size.width,
                                                                              self.navigationController.toolbar.bounds.size.height);
                     }
                     completion:nil];
}
2 голосов
/ 04 мая 2010

Большое вам спасибо за это; это прекрасно работает Однако представленный код имеет 2 ограничения, как я их испытал:

1) Перемещаемый вид просто выдвигается за пределы экрана, а не изменяет размер, чтобы соответствовать пространству, доступному после появления клавиатуры

2) Повторяющиеся уведомления из-за переключения текстовых полей продолжают применять изменение фрейма, в результате чего вид постепенно улетает за пределы экрана.

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

В liftMainViewWhenKeybordAppears :, изменять размер, а не изменять положение относительно клавиатуры:

    keyboardFrame = [self.view.window convertRect:keyboardFrame toView:self.view.superview];
    CGRect superviewFrame = [self.view.window convertRect:self.view.superview.frame toView:self.view];
    [self.view setFrame:CGRectMake(self.view.frame.origin.x, 
                               self.view.frame.origin.y,
                               self.view.frame.size.width, 
                               superviewFrame.size.height - keyboardFrame.size.height)];

В returnMainViewToInitialposition: измените анимацию на этот setFrame: (по сути, схожий с преобразованием идентичности).

    [self.view setFrame:CGRectMake(self.view.frame.origin.x, 
                               self.view.frame.origin.y,
                               self.view.frame.size.width, 
                               keyboardFrame.origin.y + keyboardFrame.size.height)];
0 голосов
/ 10 марта 2011

Вот более элегантное решение с использованием категории uiview

#import <Foundation/Foundation.h>


@interface UIView(AnimationUtils)
-(void)scrollControlToCenter:(UIView *)view;
-(void)scrollViewToOriginalPosition;
@end



#import "UIView+AnimationUtils.h"


@implementation UIView(AnimationUtils)
#pragma mark ScrollView Methods

//Method Called whenever keyboard appears
- (void)scrollControlToCenter:(UIView *)view {  
    if([view isKindOfClass:[UITextField class]]){
        CGRect viewFrame = [view frame];
        float verticalDistance = 216.0f - viewFrame.origin.y - (2*viewFrame.size.height);
        if(viewFrame.size.height >= (460 - 216)/2){
            verticalDistance = 0;
        }
        [UIView beginAnimations:@"ScrollToCenter" context:nil];
        [UIView setAnimationDuration:0.5];
        [self setFrame:CGRectMake(0, verticalDistance, self.frame.size.width, self.frame.size.height)];
        [UIView commitAnimations];
    }else if([view isKindOfClass:[UITextView class]]){
        [UIView beginAnimations:@"ScrollToTop" context:nil];
        [UIView setAnimationDuration:0.5];
        UIView *viewBG = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
        [viewBG setTag:5];
        [viewBG setBackgroundColor:[UIColor blackColor]];
        [viewBG setAlpha:0.75];
        [self addSubview:viewBG];
        [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, view.frame.size.height)];
        [self setFrame:CGRectMake(0, -view.frame.origin.y , self.frame.size.width, self.frame.size.height)];
        [self insertSubview:view atIndex:[self.subviews count] + 1];
        [UIView commitAnimations];
    }

}
-(void)scrollViewToOriginalPosition{
    [UIView beginAnimations:@"ScrollToOriginal" context:nil];
    [UIView setAnimationDuration:0.5];
    for(UIView *view in self.subviews){
        if(view.tag == 5){
            [view removeFromSuperview];
        }
    }
    [self setFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
    [UIView commitAnimations];  

}

#pragma mark -
@end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...