酒と泪とRubyとRailsと

Ruby on Rails と Objective-C は酒の肴です!

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

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

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

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


サンプル

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

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

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

ヘッダ・ファイル

1
2
3
4
5
6
7
@interface SampleViewController : UIViewController<UIScrollViewDelegate,UITextViewDelegate>

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

@end

実装ファイル

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
@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初心者なので、ぜひ間違っていたら積極的にツッコミを頂ければ泣いて喜びます。よろしくお願いします!

Special Thanks

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

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

おすすめの書籍