iOS鍵盤彈出時動畫時長失效問題

時間請你忘記我發表於2019-03-26

iOS鍵盤彈出動畫問題

今天在寫鍵盤彈出時遇見一個問題。監聽UIKeyboardWillShowNotification通知讓Label做一個移動的動畫,指定duration為15,但動畫實際完成時間卻與鍵盤彈出時間一致。

- (void)keyboardWillShow:(NSNotification *)notification {
    [UIView animateWithDuration:15 animations:^{
        CGRect frame = self.moveLabel.frame;
        frame.origin.y = 300;
        self.moveLabel.frame = frame;
    }];
}

複製程式碼

iOS鍵盤彈出時動畫時長失效問題

如果是在UIKeyboardDidShowNotification中做動畫,動畫完成時間則為指定時間。

- (void)keyboardDidShow:(NSNotification *)notification {
    [UIView animateWithDuration:5 animations:^{
        CGRect frame = self.moveLabel.frame;
        frame.origin.y = 300;
        self.moveLabel.frame = frame;
    }];
}
複製程式碼

iOS鍵盤彈出時動畫時長失效問題

這兩者的區別一個是鍵盤將要彈出,一個是鍵盤已經彈出。這跟我的動畫有什麼關係呀?

把UIKeyboardWillShowNotification通知方法中的動畫去掉,發現依舊有動畫效果。誒~好神奇~腫麼回事,難道keyboardWillShow呼叫時就處於一個Animation裡(我猜的)?

- (void)keyboardWillShow:(NSNotification *)notification {
//    [UIView animateWithDuration:15 animations:^{
        CGRect frame = self.moveLabel.frame;
        frame.origin.y = 300;
        self.moveLabel.frame = frame;
//    }];
}
複製程式碼

iOS鍵盤彈出時動畫時長失效問題

搜了好多地方都沒有找到keyboardWillShow的原理,好尷尬~ 為了驗證自己的猜測,寫了一個巢狀動畫,用來驗證巢狀的動畫執行時間為多少。

- (IBAction)moveAction:(id)sender {
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(changeText) userInfo:nil repeats:YES];

    [UIView animateWithDuration:2 animations:^{ // 外層動畫時間
        CGRect frame = self.moveLabel.frame;
        frame.origin.y = 100;                   // 外層動畫座標
        self.moveLabel.frame = frame;
        
        [UIView animateWithDuration:10 animations:^{    // 內層動畫時間
            CGRect frame = self.moveLabel.frame;
            frame.origin.y = 400;                       // 內層動畫座標
            self.moveLabel.frame = frame;
        }];
    }];
}

- (void)changeText {
    self.timeCount++;
    self.moveLabel.text = [NSString stringWithFormat:@"Time = %ld,\nFrame.origin.y = %.0f", (long)self.timeCount, self.moveLabel.frame.origin.y];
    
    if (self.timeCount > 12) {
        [self.timer invalidate];
        self.timer = nil;
    }
}
複製程式碼

iOS鍵盤彈出時動畫時長失效問題

最終效果為:動畫時間取外層動畫時間值,結果取內層動畫座標值。 所以我那個猜測還是有道理的… 希望有大神指點下keyboardWillShow的原理

更新

受到大神評論的指點,又多get到了一個知識點。
通過設定動畫的options使動畫忽略外層動畫巢狀效果,只關心自己的動畫引數。options參照www.jianshu.com/p/3723c403a…

- (void)keyboardWillShow:(NSNotification *)notification {
    [UIView animateWithDuration:15 delay:0 options:UIViewAnimationOptionOverrideInheritedDuration | UIViewAnimationOptionOverrideInheritedCurve animations:^{
        CGRect frame = self.moveLabel.frame;
        frame.origin.y = 300;
        self.moveLabel.frame = frame;
    } completion:nil];
}
複製程式碼

iOS鍵盤彈出時動畫時長失效問題

相關文章