2

I have a standard UINavigationViewController with a standard UIInteractivePopGestureRecognizer for iOS 7. I also have these well known and widely-used methods:

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

They work like this:

- (void)keyboardWillShow:(NSNotification *)notification{
    CGFloat keyboardSlideDuration = [[[notification userInfo] objectForKey: UIKeyboardAnimationDurationUserInfoKey] floatValue];

    UIViewAnimationOptions keyboardAnimationCurve = [[notification userInfo][UIKeyboardAnimationCurveUserInfoKey] integerValue]<<16;

    if (keyboardIsUp || isAnimating) return;

    isAnimating = YES;

    [UIView animateWithDuration:keyboardSlideDuration delay:0 options:(keyboardAnimationCurve | UIViewAnimationOptionBeginFromCurrentState) animations:^{
        _topConstraint.constant -= kTopConstraintR4Ratio;
        [self.view layoutIfNeeded];
    }completion:^(BOOL finished){
        keyboardIsUp = YES;
        isAnimating = NO;
    }];
}

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

    CGFloat keyboardSlideDuration = [[[notification userInfo] objectForKey: UIKeyboardAnimationDurationUserInfoKey] floatValue];

    UIViewAnimationOptions keyboardAnimationCurve = [[notification userInfo][UIKeyboardAnimationCurveUserInfoKey] integerValue]<<16;

    if (isAnimating) return;

    isAnimating = YES;

    [UIView animateWithDuration:keyboardSlideDuration delay:0 options:(keyboardAnimationCurve | UIViewAnimationOptionBeginFromCurrentState) animations:^{
        _topConstraint.constant = topConstraintOriginalValue;
        [self.view layoutIfNeeded];
    } completion:^(BOOL finished) {
        keyboardIsUp = NO;
        isAnimating = NO;
    }];
}

The thing is that UIView animateWithDuration is triggered without any respect to duration when I swipe the view back with a gesture. The whole view turns into a mess - it animates slowly when I pop the view, but when the gesture isn't finished - the view jumps up.

It looks like this:

enter image description here

How do I get rid of this strange behavior? I don't want the view to move during the transition and I want it to stay still.

EDIT:

You can download the sample project using the link here:

https://www.dropbox.com/s/034lfy49ru4pelf/SampleProject.zip

Sergey Grischyov
  • 11,995
  • 20
  • 81
  • 120

2 Answers2

3

Easy hack:

BOOL needAdjustContstrain;

Set needAdjustContstrain to YES in keyboardWillShow:

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    if (needAdjustContstrain) {
         _topContstraint.constant -=40;
    }
}
avdyushin
  • 1,906
  • 17
  • 21
-2

you need to call the layoutIfneeded method before the animation block . Check out the code below :

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

CGFloat keyboardSlideDuration = [[[notification userInfo] objectForKey: UIKeyboardAnimationDurationUserInfoKey] floatValue];

UIViewAnimationOptions keyboardAnimationCurve = [[notification userInfo][UIKeyboardAnimationCurveUserInfoKey] integerValue]<<16;

if (isAnimating) return;

isAnimating = YES;

[self.view layoutIfNeeded];
[UIView animateWithDuration:keyboardSlideDuration delay:0 options:(keyboardAnimationCurve | UIViewAnimationOptionBeginFromCurrentState) animations:^{
    _topContstraint.constant = 89;
  //
} completion:^(BOOL finished) {
    keyboardIsUp = NO;
    isAnimating = NO;
}];}

Please check the link

Community
  • 1
  • 1
Singh
  • 2,151
  • 3
  • 15
  • 30
  • 1
    Not performing layout will not perform the animation correctly in other places of the code, where animation is needed. – Léo Natan Jul 28 '14 at 11:30
  • 1
    Absolutely not a credible answer - this way the animation is not being performed correctly, just like @LeoNatan said. – Sergey Grischyov Jul 28 '14 at 11:35
  • That's not going to work and has nothing to do to the UIInteractivePopGesture – Sergey Grischyov Jul 28 '14 at 12:01
  • @SergiusGee i have tested the above code and its working fine. – Singh Jul 28 '14 at 12:04
  • @sigkill What's working fine? The animation is broken, the view still moves with the gesture recognizer. How on earth do you expect to break the `UIView` animation cycle and expect it to work? – Sergey Grischyov Jul 28 '14 at 12:14
  • @sigkill Jesus, even the link you pointed out to says: `You need to call layoutIfNeeded within the animation block.` Do you even look what you post? Within != before. – Sergey Grischyov Jul 28 '14 at 12:15