IPhone 5シミュレータ上のiOS 7.0の新しいキーボードアニメーションを理解しようとしています。キーボードが表示されたらUITableView
のサイズを変更したいのですが、正しいアニメーションの詳細を取得できません。
キーボードが表示または非表示になったときに、NSNotification
オブジェクトの情報を使用しています。
ここに私のログがあります:
Move keyboard from {{0, 920}, {320, 216}} to {{0, 352}, {320, 216}}
with duration: 0.400000
and animation curve: 7
UIViewAnimationCurveEaseInOut = 0
UIViewAnimationCurveEaseIn = 1
UIViewAnimationCurveEaseOut = 2
UIViewAnimationCurveLinear = 3
アニメーションカーブは不明な値です。どうすればよいですか?
今、私は解決策を見つけました。アニメーションは{0, 920}
から{0, 352}
の地点から始まります。問題は、UITableView
オブジェクトが{160, 568}
のサイズで開始したため、アニメーションが開始される前にUITableView
のサイズを{160, 920}
に変更したことです。
未知のアニメーションカーブに関しては、パラメータをanimationCurve << 16
に設定して、ビューアニメーションカーブからビューアニメーションオプションに変換するだけです。
値は、線形、イーズイン、イーズアウト、イージングアウトのアニメーション曲線と等しくありません。
ここに私のコードがあります:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
そして:
- (void)keyboardWillShow:(NSNotification *)aNotification {
NSDictionary *userInfo = aNotification.userInfo;
//
// Get keyboard size.
NSValue *beginFrameValue = userInfo[UIKeyboardFrameBeginUserInfoKey];
CGRect keyboardBeginFrame = [self.view convertRect:beginFrameValue.CGRectValue fromView:nil];
NSValue *endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
CGRect keyboardEndFrame = [self.view convertRect:endFrameValue.CGRectValue fromView:nil];
//
// Get keyboard animation.
NSNumber *durationValue = userInfo[UIKeyboardAnimationDurationUserInfoKey];
NSTimeInterval animationDuration = durationValue.doubleValue;
NSNumber *curveValue = userInfo[UIKeyboardAnimationCurveUserInfoKey];
UIViewAnimationCurve animationCurve = curveValue.intValue;
//
// Create animation.
CGRect tableViewFrame = self.tableView.frame;
bTableViewFrame.size.height = (keyboardBeginFrame.Origin.y - tableViewFrame.Origin.y);
self.tableView.frame = tableViewFrame;
void (^animations)() = ^() {
CGRect tableViewFrame = self.tableView.frame;
tableViewFrame.size.height = (keyboardEndFrame.Origin.y - tableViewFrame.Origin.y);
self.tableView.frame = tableViewFrame;
};
//
// Begin animation.
[UIView animateWithDuration:animationDuration
delay:0.0
options:(animationCurve << 16)
animations:animations
completion:nil];
}
IOS 7では、キーボードは文書化されていない新しいアニメーションカーブを使用します。アニメーションオプションに文書化されていない値を使用することに気づいている人もいますが、私は次のものを使用することを好みます。
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
// work
[UIView commitAnimations];
ブロックベースのアニメーションが推奨ですが、キーボード通知から返されるアニメーション曲線はUIViewAnimationCurve
ですが、ブロックベースのアニメーションに渡す必要があるオプションはUIViewAnimationOptions
です。従来のUIViewアニメーションメソッドを使用すると、値を直接パイプで渡すことができます。最も重要なことは、これは新しいドキュメント化されていないアニメーション曲線(整数値7)。また、iOS 6および7でも同様に機能します。
animateWithDuration
ブロックを使用して、その中に曲線を設定できます。それはきれいで、うまく機能します。
UIViewAnimationCurve curve = [[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue];
double duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
[UIView animateWithDuration:duration
delay:0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
[UIView setAnimationCurve:curve];
/* ANIMATION HERE */
// don't forget layoutIfNeeded if you use autolayout
}
completion:nil];
ハッピーコーディング!
[〜#〜] update [〜#〜]
私が書いたシンプルなUIViewControllerカテゴリを使用できます https://github.com/Just-/UIViewController-KeyboardAnimation
代わりにUIKeyboardWillChangeFrameNotification
を使用します。中国語キーボードなどの一部の国際キーボードは使用中に高さが変わるためです。また、このコードは、横向きモードでもキーボードの正しい高さを提供します。 (注:以下のコードはAutolayout向けです)
//set your observer, in a method like viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChange:) name:UIKeyboardWillChangeFrameNotification object:nil];
- (void)keyboardWillChange:(NSNotification *)notification {
CGRect initialRect = [notification.userInfo[UIKeyboardFrameBeginUserInfoKey] CGRectValue];
CGFloat initialHeight = self.view.frame.size.height - [self.view convertRect:initialRect fromView:nil].Origin.y;
CGRect keyboardRect = [notification.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
CGFloat newHeight = self.view.frame.size.height - [self.view convertRect:keyboardRect fromView:nil].Origin.y;
//set your constraints here, based on initialHeight and newHeight, which are the heights of the keyboard before & after animation.
[self.contentView setNeedsUpdateConstraints];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:[notification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[notification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
[self.contentView layoutIfNeeded];
[UIView commitAnimations];
}
キーボードと同じアニメーションを使用するには、文書化されていない曲線オプションを使用する必要があります。
- (void)keyboardWillHide:(NSNotification *)notification {
NSDictionary *userInfo = [notification userInfo];
CGRect rect = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
NSTimeInterval animationDuration = [[userInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
NSInteger curve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] intValue] << 16;
[UIView animateWithDuration:animationDuration delay:0.0 options:curve animations:^{
} completion:nil];
}
実際にメソッドanimateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:
は、すべてのアニメーションがiOS7およびiOS8で実行される新しい方法です。適切な持続時間、減衰、速度を設定するだけで、同じ効果が得られますが、速度/時間を変更することもできます。
In Swift 4
キーボード通知のオブザーバーを追加します。
via
NSNotificationCenter.defaultCenter().addObserver(_ observer: Any,
selector aSelector: Selector,
name aName: NSNotification.Name?,
object anObject: Any?)
セレクターを実装して、キーボードアニメーションでUIをアニメーション化します。有効なカーブ値を作成するには、UIResponder.keyboardAnimationCurveUserInfoKeyを<< 16だけシフトする必要があります
func keyboardWillShow(_ notification: Notification!) {
if let info = notification.userInfo {
let keyboardSize = info[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
let duration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double
let curveVal = (info[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber)?.intValue ?? 7 // default value for keyboard animation
let options = UIView.AnimationOptions(rawValue: UInt(curveVal << 16))
UIView.animate(withDuration: duration, delay: 0, options: options, animations: {
// any operation to be performed
}, completion: nil)
}
}
通知の登録:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
ビューのframe.Origin.yへの変更をアニメーション化して応答します。
- (void)keyboardWillShow:(NSNotification *)aNotification {
NSDictionary *userInfo = aNotification.userInfo;
NSValue *endFrameValue = userInfo[UIKeyboardFrameEndUserInfoKey];
CGRect keyboardEndFrame = [self.view convertRect:endFrameValue.CGRectValue fromView:nil];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:[aNotification.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue]];
[UIView setAnimationCurve:[aNotification.userInfo[UIKeyboardAnimationCurveUserInfoKey] integerValue]];
[UIView setAnimationBeginsFromCurrentState:YES];
CGRect searchButtonFrame = self.searchButton.frame;
searchButtonFrame.Origin.y = (keyboardEndFrame.Origin.y - searchButtonFrame.size.height);
self.searchButton.frame = searchButtonFrame;
[UIView commitAnimations];
}