上移 UIToolbar

Posted

技术标签:

【中文标题】上移 UIToolbar【英文标题】:move up UIToolbar 【发布时间】:2010-12-29 10:32:00 【问题描述】:

我的视图底部有一个 UIToolbar,我在这个工具栏中有一个 UITextField。当我开始编辑此字段时,它隐藏在键盘后面。要查看我输入的内容,我想在出现键盘时将工具栏向上移动(然后在完成编辑后将其向下移动)。

如何向上/向下移动此 UIToolbar?

【问题讨论】:

***.com/questions/1247113/… 的副本 不是重复的。这个问题是关于工具栏而不是文本字段。 【参考方案1】:

将您的 viewController 类添加到 UIKeyboardWillShowNotification/UIKeyboardWillHideNotification 的观察者列表中。然后您可以移动您的视图以使您的 textView 可见。您还可以从此通知中获取动画参数,以将您的动画与当前操作系统版本的键盘动画参数同步。这段代码我用于分页

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

【讨论】:

感谢您的出色解决方案。但我仍然无法移动工具栏。视图移动但不是我在viewDidLoadmethod 中创建的工具栏。你能给我一个提示吗?谢谢【参考方案2】:

谢谢你的工作! 这里有一点改进:

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

【讨论】:

【参考方案3】:

在上述答案的基础上,使用便捷的方法 [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];

【讨论】:

通过移位将 UIViewAnimationCurve 转换为 UIViewAnimationOptionCurve!我怎么想不出这个!?非常感谢。【参考方案4】:

非常感谢您;效果很好。但是,所呈现的代码在我的体验中存在 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)];

【讨论】:

【参考方案5】:

这是一个使用 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

【讨论】:

以上是关于上移 UIToolbar的主要内容,如果未能解决你的问题,请参考以下文章

键盘出现时UITextField上移【Swift】

关于最下方 EditText 获取焦点 界面上移的问题

jqgrid 上移下移单元格

Lind.DDD.Domain.ISortBehavor~上移与下移

解决IQKeyboard键盘引起的视图上移

IOS-当遇到tableView整体上移时的解决方案