酒と泪とRubyとRailsと

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

UITextFieldをタップした時にキーボードで隠れないようにする[Ojbective-C]

Objective-Cを触っていて、最近良くこのあたりの挙動にはまっています。 一応、この方法で現時点のデモまでは動くようになったので、とりあえず備忘録がてらのメモです。


前提条件

拙著『UIViewControllerからUIView部分を切り出す』 の方法で、UIViewUIViewControllerを分けている前提です。ということでこの記事では、UIView側への記述していきます。

ヘッダファイル

1
2
@interface OriginalView : UIView<UIScrollViewDelegate,UITextFieldDelegate>
@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
@interface OriginalView()
@property JAMValidatingTextField* activeField;
@end

@implementation OriginalView

-(void) layoutSubviews {
    [super layoutSubviews];

    // キーボード表示、非表示の際のイベントを設定
    [[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)willMoveToWindow:(UIWindow *)newWindow {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [super willMoveToWindow:newWindow];
}

#pragma mark キーボードが表示された時のイベント
- (void)keyboardWasShown:(NSNotification *)notification {
    NSDictionary *info = [notification userInfo];
    CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;

    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height + 60, 0.0);
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;
}

#pragma mark キーボードが閉じた時のイベント
- (void)keyboardWasHidden:(NSNotification *)notification {
    UIEdgeInsets contentInsets = UIEdgeInsetsZero;
    self.scrollView.contentInset = contentInsets;
    self.scrollView.scrollIndicatorInsets = contentInsets;
}

#pragma mark テキストフィールドを編集する前の場合
- (BOOL)textFieldShouldBeginEditing:(JAMValidatingTextField *)textField {
    _activeField = textField;
    return YES;
}

#pragma mark テキストフィールドの編集が完了した場合
- (void)textFieldDidEndEditing:(JAMValidatingTextField *)textField {
    _activeField = nil;
}

@end

あとがき

Objective-Cの習得に相当悪戦苦闘してまする。。。

Special Thanks

UITextFieldをタップしたときにキーボードの下に隠れないようにする - Gist

iphone - When to unsubscribe from a NSNotification in a UIView - Stack Overflow

おすすめの書籍