私は最近同じ問題に遭遇し、それを修正するのにしばらく時間がかかりました. 問題は、テキスト フィールドが ReusableCollectionView にネストされている場合、以下が機能しないことです。
[self.collectionView reloadData];
[self.textField becomeFirstResponder];
さらに、シミュレーターでは問題なく動作しましたが、デバイスでは動作しませんでした。
ビュー コントローラーをテキスト フィールド デリゲートとして設定し、実装する
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
return NO;
}
結果コレクション ビューが更新されなかったため、機能しませんでした。私の推測では、ビュー コレクションをリロードする前に、ネストされたすべてのコントロールからフォーカスを削除しようとしますが、できません。テキスト フィールド デリゲート メソッドから NO を返します。
したがって、私にとっての解決策は、システムがテキストフィールドからフォーカスを削除し、リロード後に元に戻すことでした。問題は、実際にいつそれを行うかでした。
まず、私は
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
しかし、コレクションに項目がなかった場合 (フィルタリング中の通常のケース)、このメソッドは呼び出されませんでした。
最終的に私はこれを次の方法で解決しました。-prepareForReuse と -drawRect: の 2 つのメソッドを実装する UICollectionReusableView サブクラスを作成しました。最初のものには、次の描画サイクルで drawRect 呼び出しをスケジュールする -setNeedsDesplay 呼び出しが含まれています。2 つ目は、対応するフラグが YES に設定されている場合、[self.textField becomeFirstResponder] を呼び出してフォーカスを復元します。そのため、becomeFirstResponder を「後で」呼び出すというアイデアがありましたが、遅すぎることはありません。そうしないと、キーボードの奇妙な「ジャンプ」が発生します。
カスタムの再利用可能なコレクション ビューは次のようになります。
@interface MyCollectionReusableView : UICollectionReusableView
@property (nonatomic, assign) BOOL restoreFocus;
@property (nonatomic, strong) UITextField *textField;
@end
@implementation MyCollectionReusableView
@synthesize restoreFocus;
@synthesize textField;
- (void)setTextField:(UITextField *)value {
textField = value;
[self addSubview:textField];
}
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
if (self.restoreFocus) {
[self.textField becomeFirstResponder];
}
}
- (void)prepareForReuse {
[self setNeedsDisplay];
}
次に、私のView Controllerで:
- (void)viewDidLoad {
[super viewDidLoad];
[self.collectionView registerClass:[MyCollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:HeaderReuseIdentifier];
[self.textField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
}
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
if (UICollectionElementKindSectionHeader == kind) {
MyCollectionReusableView *view = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:HeaderReuseIdentifier forIndexPath:indexPath];
//add textField to the reusable view
if (nil == view.textField) {
view.textField = self.textField;
}
//set restore focus flag to the reusable view
view.restoreFocus = self.restoreFocus;
self.restoreFocus = NO;
return view;
}
return nil;
}
- (void)textFieldDidChange:(UITextField *)textField {
self.restoreFocus = YES;
[self.collectionView reloadData];
}
おそらく最もエレガントなソリューションではありませんが、機能します。:)