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が画面の途中に有っても問題なく動作しました。










本当は、こういう当たり前にやって欲しいことを、クライアント側でやって自動的にやって欲しいものですよね。。