自動レイアウト制約のあるテーブルビューをスムーズにアニメーション化しようとしてスタックしました。私の.hの制約「keyboardHeight」への参照があり、これをIBでリンクしました。テーブルビューがポップアップしたときに、キーボードでテーブルビューをアニメーション化するだけです。これが私のコードです:
- (void)keyboardWillShow:(NSNotification *)notification
{
NSDictionary *info = [notification userInfo];
NSValue *kbFrame = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardFrame = [kbFrame CGRectValue];
CGFloat height = keyboardFrame.size.height;
[UIView animateWithDuration:animationDuration animations:^{
self.keyboardHeight.constant = -height;
[self.view setNeedsLayout];
}];
}
重要なのは、アニメーションブロックが瞬間的で、キーボードがアニメーションを終了する前に空白が表示されることです。キーボードがアニメーションしているので、基本的にはビューの白い背景が表示されます。キーボードがアニメーションしている限り、アニメーションを長持ちさせることはできません。
私はこれを間違った方法でアプローチしていますか?前もって感謝します!
このようにしてみてください:
self.keyboardHeight.constant = -height;
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:animationDuration animations:^{
[self.view layoutIfNeeded];
}];
これは(WWDCに従って)制約ベースのレイアウトを更新する正しい方法であるため、このパターンを覚えておいてください。後でNSLayoutConstraint
を呼び出す限り、setNeedsUpdateConstraints
sを追加または削除することもできます。
UITableViewControllerを使用している場合、contentInsetsを調整するために、キーボードのサイズはiOSによって自動的に調整されます。しかし、tableViewがUIViewController内にある場合、おそらくこれを使用したいと思います。
KeyboardLayoutConstraintSpring フレームワーク内。これまでに見つけた最も簡単な解決策。
次のコードを試してください。この場合、テーブルビューは画面の下端に配置されます。
- (void)keyboardWillShow:(NSNotification *)notification { // UIKeyboardWillShowNotification
NSDictionary *info = [notification userInfo];
NSValue *keyboardFrameValue = [info objectForKey:UIKeyboardFrameEndUserInfoKey];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect keyboardFrame = [keyboardFrameValue CGRectValue];
BOOL isPortrait = UIDeviceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
CGFloat keyboardHeight = isPortrait ? keyboardFrame.size.height : keyboardFrame.size.width;
// constrBottom is a constraint defining distance between bottom Edge of tableView and bottom Edge of its superview
constrBottom.constant = keyboardHeight;
// or constrBottom.constant = -keyboardHeight - in case if you create constrBottom in code (NSLayoutConstraint constraintWithItem:...:toItem:...) and set views in inverted order
[UIView animateWithDuration:animationDuration animations:^{
[tableView layoutIfNeeded];
}];
}
- (void)keyboardWillHide:(NSNotification *)notification { // UIKeyboardWillHideNotification
NSDictionary *info = [notification userInfo];
NSTimeInterval animationDuration = [[info objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
constrBottom.constant = 0;
[UIView animateWithDuration:animationDuration animations:^{
[tableView layoutIfNeeded];
}];
}
私が取ったアプローチは、キーボードのサイズに従うビューを追加することです。テーブルビューまたはテキスト入力などの下に追加すると、キーボードが表示されたときにプッシュされます。
これは、ビュー階層を設定する方法です。
NSDictionary *views = @{@"chats": self.chatsListView, @"reply": self.replyBarView, @"fakeKeyboard":self.fakeKeyboardView};
[self.view addVisualConstraints:@"V:|-30-[chats][reply][fakeKeyboard]|" views:views];
そして、キーボードサイズに続くビューの主要な部分は次のようになります。
- (void)keyboardWillShow:(NSNotification *)notification
{
// Save the height of keyboard and animation duration
NSDictionary *userInfo = [notification userInfo];
CGRect keyboardRect = [userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
self.desiredHeight = CGRectGetHeight(keyboardRect);
self.duration = [userInfo[UIKeyboardAnimationDurationUserInfoKey] floatValue];
[self animateSizeChange];
}
- (void)keyboardWillHide:(NSNotification *)notification
{
self.desiredHeight = 0.0f;
[self animateSizeChange];
}
- (CGSize)intrinsicContentSize
{
return CGSizeMake(UIViewNoIntrinsicMetric, self.desiredHeight);
}
- (void)animateSizeChange
{
[self invalidateIntrinsicContentSize];
// Animate transition
[UIView animateWithDuration:self.duration animations:^{
[self.superview layoutIfNeeded];
}];
}
この特定のビューにサイズ変更を処理させることの良い点は、ビューコントローラーに無視させることができ、アプリ内のすべての位置をシフトしたい任意の場所でこのビューを再利用できることです。
完全なファイルはこちらです https://Gist.github.com/shepting/6025439