2012-08-07 61 views
0

我的应用程序中有一个函数,当键盘显示时,视图向上移动。不幸的是有一个错误;您第一次加载视图一切工作正常,但如果您切换到另一个视图,然后切换回来,视图不再移动:(奇怪的视图行为

我添加了一些NSLog语句到我的代码来尝试和追踪问题。我正在使用NSNotification,而且工作正常,因为每次都调用方法。

然后我想也许这是一个视图坐标问题,所以我添加了打印出视图原点的语句。他们打印出正确的来源('移动'的起源),尽管视图肯定没有移动。

因此,看起来Xcode认为它已经移动了视图,但它没有。有其他人遇到过这种行为吗?


编辑:这里是一些代码

设置的通知:

 //register for keyboard notifications 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:self.view.window]; 

     //if the keyboard is already being shown because someone was entering a comment, and then they switch to a textfield, this will move the view back down. 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UITextFieldTextDidBeginEditingNotification object:self.view.window]; 

     //hide the keyboard 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:self.view.window]; 

     //hide the keyboard if we're done with the textview 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UITextViewTextDidEndEditingNotification object:self.view.window]; 

     keyboardIsShown = FALSE; 

     tempDelegate.keyboardIsInitialized = TRUE; 

的方法来显示键盘和移动视图:

-(void)keyboardWillShow:(NSNotification *)notif{ 

    NSLog(@"keyboardWillShow"); 
    NSLog(@"type: %@, keyboardIsShown: %@", sender, keyboardIsShown); 

    //double check 
    if (keyboardIsShown || !sender) { 
     NSLog(@"return"); 
     return; 
    } 

    //only adjust screen for comment box (which is a textview) 
    if(![sender isEqualToString:@"text field"] && [sender isEqualToString:@"text view"]){ 

     NSLog(@"if"); 

     NSDictionary* userInfo = [notif userInfo]; 

     // get the size of the keyboard 
     CGSize keyboardSize = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; 

     [UIView beginAnimations:@"ResizeForKeyboard" context:NULL]; 
     [UIView setAnimationBeginsFromCurrentState:YES]; 
     [UIView setAnimationDuration:0.3]; 

     NSLog(@"regular BEFORE: %@", NSStringFromCGRect(regularView.frame)); 

     regularView.frame = CGRectMake(0, - keyboardSize.height, CGRectGetWidth(imageView.bounds)*scrollView.zoomScale, CGRectGetHeight(imageView.bounds)*scrollView.zoomScale); 

     NSLog(@"regular AFTER: %@", NSStringFromCGRect(regularView.frame)); 

     [UIView commitAnimations]; 

     keyboardIsShown = YES; 


    } 
} 

和方法隐藏键盘并将视图移回:

-(void)keyboardWillHide:(NSNotification *)notif{ 

    NSLog(@"keyboardWillHide"); 

    if (!keyboardIsShown) { 
     NSLog(@"return"); 
     return; 
    } 

    [UIView beginAnimations:@"ResizeForKeyboard" context:NULL]; 
    [UIView setAnimationBeginsFromCurrentState:YES]; 
    [UIView setAnimationDuration:0.3]; 

    NSLog(@"regular BEFORE: %@", NSStringFromCGRect(regularView.frame)); 


    self.regularView.frame = CGRectMake(0, 0, CGRectGetWidth(imageView.bounds)*scrollView.zoomScale, CGRectGetHeight(self.imageView.bounds)*scrollView.zoomScale); 
    [UIView commitAnimations]; 

    NSLog(@"regular AFTER: %@", NSStringFromCGRect(regularView.frame)); 



    keyboardIsShown = NO; 
} 
+0

您是否在任何时候添加或删除NSNotification? 此外,你可以发布你的代码如何移动你的观点?那里可能有一些问题。 – random 2012-08-07 17:49:03

+0

我删除dealloc和viewDidUnload中的通知...我在代码中编辑到OP – BloonsTowerDefence 2012-08-07 17:55:37

回答

0

您是否在任何时候添加或删除NSNotification?

另外,你可以发布你的代码如何移动你的观点?那里可能有一些问题。

编辑:

因此,从什么,似乎是正在在某些时候删除您的通知,并没有被加回。

移动通知INIT到您的viewDidAppear方法,在你viewDidDissappear方法删除它们。这将确保您的视图出现或消失时分别添加或删除通知。

什么你可能做在你的viewDidLoad,其视图时首先加载(所以只有一次)这种方法只被调用时添加。所以,如果你推新视图然后弹出,它们可能会被删除,而不是加回来。

编辑:

这里是代码卡盘时,我需要用键盘进行动画,我通常使用。

#define kOFFSET_FOR_KEYBOARD 80.0 

-(void)keyboardWillShow { 
    // Animate the current view out of the way 
    if (self.view.frame.origin.y >= 0) 
    { 
     [self setViewMovedUp:YES]; 
    } 
    else if (self.view.frame.origin.y < 0) 
    { 
     [self setViewMovedUp:NO]; 
    } 
} 

-(void)keyboardWillHide { 
    if (self.view.frame.origin.y >= 0) 
    { 
     [self setViewMovedUp:YES]; 
    } 
    else if (self.view.frame.origin.y < 0) 
    { 
     [self setViewMovedUp:NO]; 
    } 
} 

-(void)textFieldDidBeginEditing:(UITextField *)sender 
{ 
    if ([sender isEqual:mailTf]) 
    { 
     //move the main view, so that the keyboard does not hide it. 
     if (self.view.frame.origin.y >= 0) 
     { 
      [self setViewMovedUp:YES]; 
     } 
    } 
} 

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

    CGRect rect = self.view.frame; 
    if (movedUp) 
    { 
     // 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. 
     rect.origin.y -= kOFFSET_FOR_KEYBOARD; 
     rect.size.height += kOFFSET_FOR_KEYBOARD; 
    } 
    else 
    { 
     // revert back to the normal state. 
     rect.origin.y += kOFFSET_FOR_KEYBOARD; 
     rect.size.height -= kOFFSET_FOR_KEYBOARD; 
    } 
    self.view.frame = rect; 

    [UIView commitAnimations]; 
} 


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

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

- (void)viewWillDisappear:(BOOL)animated 
{ 
    // unregister for keyboard notifications while not visible. 
    [[NSNotificationCenter defaultCenter] removeObserver:self 
              name:UIKeyboardWillShowNotification 
              object:nil]; 

    [[NSNotificationCenter defaultCenter] removeObserver:self 
              name:UIKeyboardWillHideNotification 
              object:nil]; 
} 
+0

请发布请求更多信息作为评论,而不是答案。 – 2012-08-07 17:42:23

+0

生病编辑一些代码到我的答案,1秒 – BloonsTowerDefence 2012-08-07 17:43:45

+0

你认为通知是问题? ' - (void)keyboardWillShow:(NSNotification *)notify'每次都会被调用...我会尝试一下你的建议,谢谢! – BloonsTowerDefence 2012-08-07 18:18:41

1

你使用:

-(void) viewWillDisappear:(BOOL)animated { 
    NSLog (@"Unregister for keyboard events"); 
    [[NSNotificationCenter defaultCenter] 
       removeObserver:self]; 
} 

如果这不是它尝试做对viewWillAppear中的观点..的位置的检查,如果它显示的键盘了..驳回W/O使用动画。

+0

不,我正在做'[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; '4个通知。并在'dealloc' – BloonsTowerDefence 2012-08-07 18:04:27

+0

这绝对是问题 – BloonsTowerDefence 2012-08-07 18:56:58

1

您是初始化regularViewviewWillAppear:还是viewDidAppear:?如果是这样,您应该将初始化移至viewDidLoad

当你确认它是,该解释是viewWillAppear:可以被称为一种观点的一生很多次,所以它通常是不恰当的构建UI层次结构中viewWillAppear:因为你最终会与重复的视图层次。

+0

我认为这绝对是我的问题之一 – BloonsTowerDefence 2012-08-07 18:55:59