UITextViewがキーボードで隠れてしまう
iOSアプリでキーボード表示するとUITextViewが隠れてしまう問題が起きたので、調査しました。
参考にしたのは、以下の記事2つです。
・UITextView がキーボードに隠れないようにする
・キーボード表示するとTextViewが隠れてしまう問題
ただし、どちらも試してみたのですが、フルサイズでUITextViewを表示している際は良いのですが、UITextViewの上部になにか置いてる場合等は、問題が起こってしまったり、キーボードを閉じる際に問題が生じてしまったので、以下のように改善しました。良いとこ取りな感じで。
.hファイル
@interface TestViewController : UIViewController<UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource> { CGRect textViewFrameSaved_; BOOL registered_; } @property (strong, nonatomic) IBOutlet UITextView *textView;
.mファイル
- (void)viewWillAppear:(BOOL)animated { // super [super viewWillAppear:animated]; // Register for notifiactions if (!registered_) { NSNotificationCenter *center; center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; registered_ = YES; } } - (void)viewWillDisappear:(BOOL)animated { // super [super viewWillDisappear:animated]; // Unregister from notification center if (registered_) { NSNotificationCenter *center; center = [NSNotificationCenter defaultCenter]; [center addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [center addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; registered_ = NO; } } - (void)keyboardWillShow:(NSNotification*)notification { textViewFrameSaved_ = _textView.frame; // Get userInfo NSDictionary *userInfo; userInfo = [notification userInfo]; // Calc overlap of keyboardFrame and textViewFrame CGFloat overlap; CGRect keyboardFrame; CGRect textViewFrame; keyboardFrame = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; keyboardFrame = [_textView.superview convertRect:keyboardFrame fromView:nil]; textViewFrame = _textView.frame; overlap = MAX(0.0, CGRectGetMaxY(textViewFrame) - CGRectGetMinY(keyboardFrame)); // Calc textViewFrameEnd CGRect textViewFrameEnd; textViewFrameEnd = _textView.frame; textViewFrameEnd.size.height -= overlap; // Animate frame of _textView NSTimeInterval duration; UIViewAnimationCurve animationCurve; void (^animations)(void); duration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; animationCurve = [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue]; animations = ^(void) { _textView.frame = textViewFrameEnd; }; [UIView animateWithDuration:duration delay:0.0 options:(animationCurve << 16) animations:animations completion:nil]; } - (void)keyboardWillHide:(NSNotification*)notification { if (!CGRectIsEmpty(textViewFrameSaved_)) { _textView.frame = textViewFrameSaved_; textViewFrameSaved_ = CGRectZero; } }
自分はこれで、UITextViewが画面の途中に有っても問題なく動作しました。
本当は、こういう当たり前にやって欲しいことを、クライアント側でやって自動的にやって欲しいものですよね。。