Appleのメッセージアプリの下部のテキスト入力バーと同様の配置動作を実現しようとしています。
私は多くのアプローチを試し、高低を検索し、同様の質問がたくさんありますが、満足できるものはありませんでした。
指定します:
UIToolbar
があります提案されたソリューション:
このソリューションは、2番目の要件の特殊なケースを満たしていません(ツールバーは、キーボードが表示されたり消えたりするときにキーボードをたどることです):
UIScrollViewKeyboardDismissMode
が導入されました。キーボードを閉じるためのインタラクティブなジェスチャーを有効にします。ユーザーがキーボードの上端を超えてパンすると、キーボードフレームが徐々に追従します。このソリューションは、この動作に対応するために何もせず、ツールバーをアニメーション化された位置に取り残します。さらに、このソリューションは、3番目の要件の特殊なケースも満たせません(キーボードが表示されている場合、ツールバーはキーボードの上に留まる必要があります) :
このソリューションの別の問題:
次に提案される解決策:
UIResponder
のinputAccessoryView
を使用この解決策は、ツールバーを手動でアニメートすることのすべての欠点を解決するため、Appleがこの種の動作をサポートすることを意図した方法のようです。ただし、このソリューションでは、4番目の要件(が非表示の場合、ツールバーはビューの下部にある(ドッキングされた)ままです)。
解決策はUIResponder
のinputAccessoryView
を使用することですが、どういうわけかinputAccessoryView
をビューの下に移動させないようにすることです。これを実現するためのきれいなコードを探しています。精巧な、ほとんど高貴な試みが他の場所にありますが、前述のように、それらは要件を満たしていません。
私の特定のケースでは、UINavigationController
の意図された動作ではないため、追加の問題を伴うUINavigationController
のツールバーを使用したいと考えています。関係なく、私はそれを達成するためにいくつかのハッキーな修正を導入したいと思っています。
Jason Foreman(@threeve)による "the"ソリューションが示されました。 View Controller(はい、View Controller)にinputAccessoryView:
そして、ドッキングしたいビューを一番下に戻し、キーボードで移動します。それはただ動作します。ビューは実際にはビュー階層にある必要はなく、View Controllerによって自動的に挿入されます。
編集:canBecomeFirstResponderも実装し、YESを返します(Max Seelemannが述べています)。 reloadInputViewsも便利です。
Swiftバージョン:
ツールバー(私の場合は 'myToolBar
')をView Controllerに接続します。次に、canBecomeFirstResponder
メソッドをオーバーライドし、ゲッターinputAccessoryView
変数をオーバーライドします。また、self.myToolBar.removeFromSuperview()
を追加することを忘れないでください。そうしないと、xcodeが文句を言います。
class ViewController: UIViewController {
@IBOutlet var myToolBar: UIToolbar!
override func canBecomeFirstResponder() -> Bool {
return true
}
override var inputAccessoryView:UIView{
get{
return self.myToolBar
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.myToolBar.removeFromSuperview()
}
}
ですから、これは古い投稿であり、これを解決したかどうかはわかりませんが、これを機能させる方法を見つけました。 inputAccessoryViewにはバグがあると思いますが、メッセージアプリと同じように振る舞うためのハッキングソリューションを作成しました。回避策を実装するために必要なすべてのコードを提供したと思います。私は、近い将来いつかより適切なブログ投稿を作成し、私の調査結果をより詳細に説明するつもりです。ご質問は、私に知らせてください。
@property(nonatomic,assign)BOOL isFirstKeyboard; //workaround for keyboard bug
@property(nonatomic,assign)BOOL isViewAppear;
@property(nonatomic,strong)ChatBarView *chatView; //custom chat bar view
@property(nonatomic,strong)UIView *footerPadView; //just to add some Nice padding
////////////////////////////////////////////////////////////////////////////////////////////////////
//in the view did load
- (void)viewDidLoad
{
//more app specific code...
self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;
self.chatView.textView.inputAccessoryView = self.chatView;
}
////////////////////////////////////////////////////////////////////////////////////////////////////
-(void)done
{
self.isFirstKeyboard = YES;
[self.chatView.textView becomeFirstResponder];
}
////////////////////////////////////////////////////////////////////////////////////////////////////
- (void) moveTextViewForKeyboard:(NSNotification*)aNotification up:(BOOL)up
{
if(!self.isViewAppear)
return;
//NSLog(@"keyboard is: %@", up ? @"UP" : @"Down");
if(!up && !self.isFirstKeyboard)
[self performSelector:@selector(done) withObject:nil afterDelay:0.01];
else if(!up & self.isFirstKeyboard)
{
self.isFirstKeyboard = NO;
[self.view addSubview:self.chatView];
CGRect frame = self.chatView.frame;
frame.Origin.y = self.view.frame.size.height - self.chatView.frame.size.height;
self.chatView.frame = frame;
}
else
{
NSDictionary* userInfo = [aNotification userInfo];
NSTimeInterval animationDuration;
UIViewAnimationCurve animationCurve;
CGRect keyboardEndFrame;
[[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&animationCurve];
[[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&animationDuration];
[[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] getValue:&keyboardEndFrame];
// Animate up or down
[UIView beginAnimations:nil context:nil];
if(up)
[UIView setAnimationDuration:0.2];
else
[UIView setAnimationDuration:0.3];
[UIView setAnimationCurve:animationCurve];
CGRect frame = self.footerPadView.frame;
CGRect keyboardFrame = [self.view convertRect:keyboardEndFrame toView:nil];
if (up)
frame.size.height = keyboardFrame.size.height - self.chatView.frame.size.height;
else
frame.size.height = 0;
self.footerPadView.frame = frame;
self.tableView.tableFooterView = self.footerPadView;
[UIView commitAnimations];
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)keyboardWillShow:(NSNotification *)aNotification {
[self moveTextViewForKeyboard:aNotification up:YES];
}
////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)keyboardWillHide:(NSNotification *)aNotification
{
[self moveTextViewForKeyboard:aNotification up:NO];
}
////////////////////////////////////////////////////////////////////////////////////////////////////