UICollectionViewのカスタムセル上にて、キーボードが出てきた時に画面を良い感じにスクロールさせる。（追記あり）

##今回の目的
ViewControllerのライフサイクルが存在しないUICollectionViewCellにて、
キーボードが現れた時に画面を良い感じにスクロールさせる。

ViewControllerのライフサイクルを活用する場合は下記記事をご参照下さい。
（とても参考になります）
[UIScrollVIewの上でも、キーボードが現れたときにいい感じにスクロールする](https://qiita.com/akaneburyo/items/893c182db347cd5122f7
)

UICollectionViewCellはUIViewControllerを継承していないので、
UIViewControllerのライフサイクルが利用できないので、
通知の登録、解除のタイミングがありません。

###実装の方針
UITextFieldDelegateの下記デリゲートメソッドを利用して、
最新の押下されたTextFieldか判定する。

```
///テキストフィールドを編集する直前に呼び出される
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
    return YES;
}

///テキストフィールドの編集が終了する直後に呼び出される
- (void)textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason{
    //行いたい処理を記載する
}
```

###ロジック
今回のパターンで想定としない処理パターンが１点あります。
**Aテキストフィールドを押下後にキーボードを下げずに、
Bテキストフィールドを押下した場合です。**

このような処理をされた場合、内部的にはデリゲートメソッドの呼び出しは
**A:編集直前
B:編集直前
A:編集終了直後**　と呼び出されます。

仮に編集直後にスクロールを0,0にして元に戻すとしていたら、
Bが適切なスクロール位置に設定されません。

なので、クラスにインスタンス変数を追加して、
**「現在押下されているTextField」**を保存して参照可能にしたいと思います。

```
///テキストフィールドの編集が終了する直後に呼び出される
- (void)textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason{
    //行いたい処理を記載する
   if([textField isEqual self.selectedTextField]){
      [self.scrollView setContentOffset:CGPointMake(0, 0)];
   }
}
```

###解説
>**A:編集直前
B:編集直前
A:編集終了直後**

先ほど説明した手順で問題があるのがA編集終了直後でBを編集中なのに、
スクロールを(0,0)に戻している点です。

なので、終了直後に引数で渡されているTextFieldは編集中のTextFieldか、
インスタンス変数と比較してチェックしています。



#コード全文
```
#import "CustomCollectionViewCell.h"

@interface CustomCollectionViewCell()<UITextFieldDelegate>
@property (weak, nonatomic) IBOutlet UITextField *topTextFiled;
@property (weak, nonatomic) IBOutlet UITextField *bottomTextField;
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;

///現在フォーカスされているTextField
@property (nonatomic) UITextField *selectedTextField;
@end
@implementation CustomCollectionViewCell

- (void)awakeFromNib {
    [super awakeFromNib];
    self.topTextFiled.delegate = self;
    self.bottomTextField.delegate = self;

}

///テキストフィールドを編集する直前に呼び出される
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
    
    self.selectedTextField = textField;
    
    switch (textField.tag) {
        case 0:
            [self.scrollView setContentOffset:CGPointMake(0, 0)];
            break;
        case 1:
            [self.scrollView setContentOffset:CGPointMake(0, textField.frame.origin.y - 50)];

            break;
            
        default:
            break;
    }
    return YES;
}

///テキストフィールドの編集が終了する直後に呼び出される
- (void)textFieldDidEndEditing:(UITextField *)textField reason:(UITextFieldDidEndEditingReason)reason{
    if([textField isEqual:self.selectedTextField]){
        [self.scrollView setContentOffset:CGPointMake(0, 0)];
    }
}




@end

```

##補足
参照記事などではキーボードの高さ分、スクロール位置を調整しておりますが、
本クラス内では通知で受け取れるのですが、
解除するタイミングが無いのでキーボードの取得は難しそうですね。

~~親CollectionViewで通知解除とかいちいちやれば出来るかもです。
改良したらまた投稿します。~~

途中で書いた `[self.scrollView setContentOffset:CGPointMake(0, textField.frame.origin.y - 50)];`ですが、一番上から50pt開ければ入力しやすいだろう、
という事で50に設定しております。

###調査を追加し、記事を追加しました。
[UICollectionViewCell（カスタムセル）で通知を受け取り、キーボードが出た時に良い感じにスクロールさせて戻る。](https://qiita.com/godaikun_method/items/42b5bc5d4367b2f54410)