2009-12-23 90 views
9

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

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

+0

重复的http://stackoverflow.com/questions/1247113/iphone-keyboard-covers-text-field/1533847#1533847 – cidered 2009-12-23 23:34:31

+0

不是重复。这个问题是关于工具栏而不是文本字段。 – phatmann 2014-03-07 01:33:15

回答

13

将您的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]; 
} 
+0

谢谢你的好解决方案。但我仍然无法移动工具栏。视图移动,但不是我在'viewDidLoad'方法中创建的ToolBar。你能给我一个提示吗?谢谢 – JFS 2013-06-12 19:49:38

8

感谢那些工作! 这是一个小小的改进:

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

非常感谢你这样做;它的效果很好。然而,由于提供的代码有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

下面是使用的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 
5

建筑类上面的答案和使用的便利方法的更好的解决方案[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]; 
} 
+0

通过转换将UIViewAnimationCurve转换为UIViewAnimationOptionCurve!为什么我不能拿出这个!?非常感谢。 – 2014-04-30 12:01:44