Objective-C
iOS
UITextField

キーボードを開いたときにTextFieldが隠れないようにする

Objective-cを初めて触って
割りと詰まったので備忘録的な感じで

諸々初期設定

@interface HogeViewController ()
@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;
@property (strong, nonatomic) IBOutlet UIView *contentView;

// 全てのUITextFieldに紐付けておきます
@property (strong, nonatomic) IBOutletCollection(UITextField) NSArray *textFields;
@end

@implementation HogeViewController {
    // オフセット
    CGPoint _offset;
}

キーボードが開いた時の通知登録

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];

実装部

- (void)keyboardWillShow:(NSNotification*)notification {
    //アニメーション終了時のキーボードのCGRect
    CGRect keyboardRect = [[notification.userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
    // アニメーションにかかる時間
    NSNumber *duration = [notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey];
    // アニメーションのタイプ
    unsigned int curve = [(NSNumber *)[notification.userInfo 
    objectForKey:UIKeyboardAnimationCurveUserInfoKey] unsignedIntValue];

    // フォーカス中のテキストフィールド取得
    UIView *firstResponder = nil;
    for (UIView *textField in _textFields) {
        if ([textField isFirstResponder]) {
            firstResponder = textField;
            break;
        }
    }
    if (firstResponder == nil) {
        return;
    }

    // キーボードサイズを取得
    CGPoint location = [_contentView convertPoint:CGPointZero 
    fromView:firstResponder];
    CGFloat offsetY = location.y + firstResponder.bounds.size.height - (_scrollView.bounds.size.height - keyboardRect.size.height);
    if (offsetY < _scrollView.contentOffset.y) {
        _scrollView.scrollEnabled = NO;
        return;
    }

    // キーボードの高さ分余白を挿入
    UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardRect.size.height, 0.0);
    _scrollView.contentInset = contentInsets;
    _scrollView.scrollIndicatorInsets = contentInsets;


    if (offsetY < 0) offsetY = 0;
    if (_offset.y == 0) {
        _offset = _scrollView.contentOffset;
    }

    [UIView animateWithDuration:[duration doubleValue]
                          delay:0.0
                        options:curve
                     animations:^{
                         // キーボードの高さ分を調整
                         _scrollView.contentOffset = CGPointMake(0, offsetY);
                     }
                     completion:^(BOOL finished) {
                     }];
}

キーボードの閉じ方や閉じたときの処理等も機会があれば書きます。