3

I am using following code to animate view's position according to keyboard movement. The code works fine under iOS 7, however it causes strange behaviour under iOS 8:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];

- (void) keyboardWillShow:(NSNotification*) aNotification {  
    NSDictionary* keyboardInfo = [aNotification userInfo];
    NSTimeInterval time = [keyboardInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    UIViewAnimationCurve curve = [keyboardInfo[UIKeyboardAnimationCurveUserInfoKey] intValue];
    CGRect keyboardFrameEnd = [[keyboardInfo valueForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    double offset = keyboardFrameEnd.size.width > keyboardFrameEnd.size.height ? keyboardFrameEnd.size.height : keyboardFrameEnd.size.width;

    [UIView beginAnimations:@"moveWindow" context:nil];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationCurve:curve];
    [UIView setAnimationDuration:time];

    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y + offset, self.frame.size.width, self.frame.size.height);

    [UIView commitAnimations];
}

Unfortunately, the answers mentioned in Is there a change to the behaviour of UIKeyboardWillShowNotification in iOS 8? and iOS8: What's going on with moving views during keyboard transitions? are out of the question:

  • The source code base is very large and old and use neither storyboard nor Auto Layout features.
  • I don't want to use UIKeyboardDidShowNotification event because the keyboard is already visible and the animation looks terrible (however, the problem is gone when using this type of notification).

Oddly enough, I found out that the problem is gone when the feature is used in the very first screen of the application. Further tests showed that removing MKMapView from one of the previous screens solves this issue. I triple checked that MKMapView is used and disposed correctly. Every allocated instance is gone way before the above code is executed.

After hours of testing and debugging I noticed in a visual hierarchy debugger (How do I inspect the view hierarchy in iOS?) that there are constraints added under UILayoutContainerView and UINavigationTransitionView. These constraints are not present when the MKMapView control is removed from the previous screen. I tried playing with every possible combination of setTranslatesAutoresizingMaskIntoConstraints: setup and could not find any resolution yet. Is it some sort of bug in iOS 8 itself or is there another way to animate view along with the keyboard?

Community
  • 1
  • 1
turekj
  • 151
  • 7
  • Can you show some code where you are creating the views. Specifically the code that you are changing when it "starts to work". – Fogmeister Oct 20 '14 at 14:00

1 Answers1

0

I'm not sure about the code itself but from the documentation about those animation methods...

Use of this method is discouraged in iOS 4.0 and later. You should use the block-based animation methods to specify your animations instead.

The correct way to animate you view is...

[UIView animateWithDuration:time
                      delay:0
                    options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^{
                     self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y + offset, self.frame.size.width, self.frame.size.height);
                 }
                 completion:nil];

Edit

OK, it's not AutoLayout (I think) but I'll leave this here anyway as you need to change it and I'll wait for more information in the question.

Fogmeister
  • 76,236
  • 42
  • 207
  • 306