UITextViewがキーボードに隠れないように&完了ボタン設置[Objective-C]


UITextViewを複数行のTextFieldするときに次のことができると汎用的で捗ると思います。

* UITextViewが選択された時にキーボードで隠れない
* 完了ボタンが表示されている
* Doneボタンでキーボードが閉じる

ということで上記を実現するためのコードを書いていきます!


🍄 サンプル

まずは動作サンプルです!

iOSシミュレータのスクリーンショット_2014_08_16_11_29_22

本当はアニgifにしたいんですが、テストデータ等々あってちょっとおこられそうですので、静止画サンプルです!

🤔 ヘッダ・ファイル

@interface SampleViewController : UIViewController

// 以下はStoryBoardと紐付けているものとします
@property IBOutlet UIScrollView *scrollView;
@property IBOutlet UITextView *textView;

@end

🐡 実装ファイル

@implementation SampleViewController

#pragma mark ビューが表示されるたびに呼ばれる
-(void)viewDidAppear:(BOOL)animated {
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super viewDidDisappear:animated];

// キーボード表示、非表示の際のイベントを設定
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasHidden:)
name:UIKeyboardDidHideNotification object:nil];
}

#pragma mark ビューが閉じる場合に呼び出される
-(void) viewWillDisappear:(BOOL)animated {
// キーボード表示・非表示時のイベント削除
[[NSNotificationCenter defaultCenter] removeObserver:self];

[super viewWillDisappear:animated];
}

#pragma mark ビューの設定
-(void)renderView {
[self setTextView];
}

#pragma mark review UTTextViewの設定
- (void)setReview {
_textView.delegate = self;

_textView.layer.borderColor = [UIColor lightGrayColor].CGColor;
_textView.layer.borderWidth = 1;
_textView.clipsToBounds = YES;
_textView.layer.cornerRadius = 10.0f;

// ViewとDoneボタンの作成
UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
keyboardDoneButtonView.barStyle = UIBarStyleBlack;
keyboardDoneButtonView.translucent = YES;
keyboardDoneButtonView.tintColor = nil;
[keyboardDoneButtonView sizeToFit];

// 完了ボタンとSpacerの配置
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:@"完了" style:UIBarButtonItemStyleBordered target:self action:@selector(doneBtnClicked)];
UIBarButtonItem *spacer1 = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *spacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:spacer, spacer1, doneButton, nil]];

// Viewの配置
_textView.inputAccessoryView = keyboardDoneButtonView;
}

#pragma mark 完了ボタンのクリック
-(void)doneBtnClicked {
[_textView resignFirstResponder];
}

#pragma mark キーボードが表示された時のイベント
- (void)keyboardWasShown:(NSNotification *)notification {
NSDictionary *info = [notification userInfo];
CGSize keyboardSize = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
CGPoint scrollPoint = CGPointMake(0.0f, keyboardSize.height);
[_scrollView setContentOffset:scrollPoint animated:YES];
}

#pragma mark キーボードが閉じた時のイベント
- (void)keyboardWasHidden:(NSNotification *)notification {
[_scrollView setContentOffset:CGPointMake(0.0f, 80.0f) animated:YES];
}

#pragma mark Doneでキーボードを閉じる
- (BOOL) textView: (UITextView*) textView shouldChangeTextInRange: (NSRange) range replacementText: (NSString*) text {
if ([text isEqualToString:@"\n"]) {
[textView resignFirstResponder];
return NO;
}
return YES;
}

@end

😎 お願い

まだまだObjective-C初心者ですので、ぜひ間違っていたら積極的にツッコミをいただければ泣いて喜びます。よろしくお願いします!

🐝 参考リンク

iphone - How do I dismiss a UITextView using the Done keyboard button? - Stack Overflow

UITextFieldがキーボードに隠れないようにする : でじゃぶろぐ

🖥 VULTRおすすめ

VULTR」はVPSサーバのサービスです。日本にリージョンがあり、最安は512MBで2.5ドル/月($0.004/時間)で借りることができます。4GBメモリでも月20ドルです。 最近はVULTRのヘビーユーザーになので、「ここ」から会員登録してもらえるとサービス開発が捗ります!

📚 おすすめの書籍