今天在寫鍵盤彈出時碰見一個問題。監聽UIKeyboardWillShowNotification通知讓Label作一個移動的動畫,指定duration爲15,但動畫實際完成時間卻與鍵盤彈出時間一致。bash
- (void)keyboardWillShow:(NSNotification *)notification {
[UIView animateWithDuration:15 animations:^{
CGRect frame = self.moveLabel.frame;
frame.origin.y = 300;
self.moveLabel.frame = frame;
}];
}
複製代碼
若是是在UIKeyboardDidShowNotification中作動畫,動畫完成時間則爲指定時間。ide
- (void)keyboardDidShow:(NSNotification *)notification {
[UIView animateWithDuration:5 animations:^{
CGRect frame = self.moveLabel.frame;
frame.origin.y = 300;
self.moveLabel.frame = frame;
}];
}
複製代碼
這二者的區別一個是鍵盤將要彈出,一個是鍵盤已經彈出。這跟個人動畫有什麼關係呀?動畫
把UIKeyboardWillShowNotification通知方法中的動畫去掉,發現依舊有動畫效果。誒~好神奇~腫麼回事,難道keyboardWillShow調用時就處於一個Animation裏(我猜的)?spa
- (void)keyboardWillShow:(NSNotification *)notification {
// [UIView animateWithDuration:15 animations:^{
CGRect frame = self.moveLabel.frame;
frame.origin.y = 300;
self.moveLabel.frame = frame;
// }];
}
複製代碼
搜了好多地方都沒有找到keyboardWillShow的原理,好尷尬~ 爲了驗證本身的猜想,寫了一個嵌套動畫,用來驗證嵌套的動畫執行時間爲多少。3d
- (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;
}
}
複製代碼
最終效果爲:動畫時間取外層動畫時間值,結果取內層動畫座標值。 因此我那個猜想仍是有道理的… 但願有大神指點下keyboardWillShow的原理code
受到大神評論的指點,又多get到了一個知識點。
經過設置動畫的options使動畫忽略外層動畫嵌套效果,只關心本身的動畫參數。options參照www.jianshu.com/p/3723c403a…orm
- (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];
}
複製代碼