biegnę na ten sam problem niedawno i zajęło to trochę czasu, aby to naprawić. Problem polega na tym, że gdy pole tekstowe jest zagnieżdżone w ReusableCollectionView, poniższe elementy nie działają.
[self.collectionView reloadData];
[self.textField becomeFirstResponder];
Co więcej, dla mnie działa dobrze na symulatorze, ale nie działa na urządzeniu.
ustawienie widoku kontrolera jako delegat pola tekstowego i wdrażaniu
- (BOOL)textFieldShouldEndEditing:(UITextField *)textField {
return NO;
}
nie działa, bo jak widok kolekcja wynik nie odświeżyć. Zgaduję, że - przed ponownym wczytaniem jego kolekcji kolekcja próbuje usunąć fokus ze wszystkich zagnieżdżonych kontrolek, ale nie może - zwracamy NO z metody delegowania pola tekstowego.
Rozwiązaniem dla mnie było umożliwienie systemowi usunięcia fokusu z pola tekstowego, a następnie odzyskanie go po ponownym załadowaniu. Pytanie brzmiało, kiedy faktycznie to zrobić.
Najpierw próbowałem to zrobić w
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
ale kiedy nie było żadnych przedmiotów w kolekcji (co jest normalne przypadek podczas filtrowania) metoda ta nie sprawdzony.
Ostatecznie rozwiązałem to w następujący sposób. Utworzona podklasa UICollectionReusableView implementuje dwie metody: -prepareForReuse i -drawRect :. Pierwsza zawiera -setNeedsDesplay wywołanie, które planuje wywołanie drawRect w następnym cyklu rysowania. Drugi przywraca fokus poprzez wywołanie [self.textField sięFirstResponder], jeśli odpowiednia flaga jest ustawiona na YES. Tak więc pomysł polegał na tym, aby zadzwonić do "przyszłego", ale nie za późno, bo w przeciwnym razie dzieje się dziwne "skakanie" klawiatury.
Mam zwyczaj wielokrotnego użytku widok kolekcja wygląda następująco:
@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];
}
Wtedy moim zdaniem Kontroler:
- (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];
}
nie
Prawdopodobnie najbardziej eleganckie rozwiązanie, ale działa. :)
Dziękuję za zadanie tego pytania. – GeneCode