2009-12-23 85 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