奇怪的观点行为

时间:2012-08-07 17:35:29

标签: objective-c uiview

我的应用程序中有一个功能,只要键盘显示,它就会向上移动视图。不幸的是有一个bug;第一次加载视图时一切正常,但如果切换到另一个视图,然后切换回来,视图就不再移动:(

我在代码中添加了一些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;
}

3 个答案:

答案 0 :(得分:1)

你正在使用:

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

如果不是这样的话,请尝试检查viewWillAppear上视图的位置..如果它显示键盘已启动...使用动画解雇它。

答案 1 :(得分:1)

您是在regularView还是viewWillAppear:初始化viewDidAppear:?如果是这种情况,您应该将初始化移至viewDidLoad

正如您确认的那样,解释是视图的生命周期可能会多次调用viewWillAppear:,因此通常不适合在viewWillAppear:中构建UI层次结构,因为您最终会重复的视图层次结构。

答案 2 :(得分: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];
}