Keyboard “WillShow” and “WillHide” vs. Rotation

前端 未结 7 626
青春惊慌失措
青春惊慌失措 2021-01-31 04:56

I\'ve got a view controller listening for both UIKeyboardWillShowNotification and UIKeyboardWillHideNotification. The handlers for these notifications adjust various parts of th

7条回答
  •  广开言路
    2021-01-31 05:07

    Recently I've wrote a blog post about this exact problem you've described and how to solve it with a short and elegant way. Here is the link to the post: Synchronizing rotation animation between the keyboard and the attached view

    If you don't want to dive into the long explanation described in the blog post here is a short description with a code example:

    The basic principle is to use the same method that everyone uses - observing keyboard notifications to animate the attached view up and down. But in addition to that, you have to cancel these animations when the keyboard notifications are fired as a consequence of interface orientation change.

    Rotation example without animation cancellation custom on interface orientation change:

    Rotation example with animation cancellation on interface orientation change:

    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated];
    
        [[NSNotificationCenter defaultCenter]
                addObserver:self selector:@selector(adjustViewForKeyboardNotification:)
                name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter]
                addObserver:self selector:@selector(adjustViewForKeyboardNotification:)
                name:UIKeyboardWillHideNotification object:nil];
    }
    
    - (void)viewDidDisappear:(BOOL)animated {
        [super viewDidDisappear:animated];
    
        [[NSNotificationCenter defaultCenter]
                removeObserver:self name:UIKeyboardWillShowNotification object:nil];
        [[NSNotificationCenter defaultCenter]
                removeObserver:self name:UIKeyboardWillHideNotification object:nil];
    }
    
    - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
        [super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
        self.animatingRotation = YES;
    }
    
    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
        [super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
        self.animatingRotation = NO;
    }
    
    - (void)adjustViewForKeyboardNotification:(NSNotification *)notification {
        NSDictionary *notificationInfo = [notification userInfo];
    
        // Get the end frame of the keyboard in screen coordinates.
        CGRect finalKeyboardFrame = [[notificationInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    
        // Convert the finalKeyboardFrame to view coordinates to take into account any rotation
        // factors applied to the window’s contents as a result of interface orientation changes.
        finalKeyboardFrame = [self.view convertRect:finalKeyboardFrame fromView:self.view.window];
    
        // Calculate new position of the commentBar
        CGRect commentBarFrame = self.commentBar.frame;
        commentBarFrame.origin.y = finalKeyboardFrame.origin.y - commentBarFrame.size.height;
    
        // Update tableView height.
        CGRect tableViewFrame = self.tableView.frame;
        tableViewFrame.size.height = commentBarFrame.origin.y;
    
        if (!self.animatingRotation) {
            // Get the animation curve and duration
            UIViewAnimationCurve animationCurve = (UIViewAnimationCurve) [[notificationInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
            NSTimeInterval animationDuration = [[notificationInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    
            // Animate view size synchronously with the appearance of the keyboard. 
            [UIView beginAnimations:nil context:nil];
            [UIView setAnimationDuration:animationDuration];
            [UIView setAnimationCurve:animationCurve];
            [UIView setAnimationBeginsFromCurrentState:YES];
    
            self.commentBar.frame = commentBarFrame;
            self.tableView.frame = tableViewFrame;
    
            [UIView commitAnimations];
        } else {
            self.commentBar.frame = commentBarFrame;
            self.tableView.frame = tableViewFrame;
        }
    }
    

    This answer was also posted in similar question: UIView atop the Keyboard similar to iMessage App

提交回复
热议问题