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;
}
4

3 回答 3

1

你正在用吗:

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

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

于 2012-08-07T17:57:29.307 回答
1

你是regularViewviewWillAppear:or中初始化viewDidAppear:吗?如果是这种情况,您应该将初始化移至viewDidLoad

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

于 2012-08-07T18:48:55.903 回答
0

您是否随时添加或删除 NSNotification?

另外,您可以发布您的代码以了解如何移动您的视图吗?那里可能有一些问题。

编辑:

因此,从看起来您的通知在某个时候被删除并且没有被添加回来。

将通知初始化移动到您的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];
}
于 2012-08-07T17:40:24.080 回答