Ich bin überrascht, wie viele Antworten hier ein einfaches Konzept nicht verstehen: Die Navigation durch Steuerelemente in Ihrer Anwendung ist nicht etwas, was die Ansichten selbst tun sollten. Es ist die Controller Die Entscheidung, welche Kontrolle der nächste Ersthelfer sein soll, ist Aufgabe der Kommission.
Außerdem bezogen sich die meisten Antworten nur auf die Vorwärtsnavigation, aber die Benutzer möchten vielleicht auch rückwärts navigieren.
Also habe ich mir Folgendes ausgedacht. Ihr Formular sollte von einem View-Controller verwaltet werden, und View-Controller sind Teil der Responder-Kette. Es steht Ihnen also völlig frei, die folgenden Methoden zu implementieren:
#pragma mark - Key Commands
- (NSArray *)keyCommands
{
static NSArray *commands;
static dispatch_once_t once;
dispatch_once(&once, ^{
UIKeyCommand *const forward = [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:0 action:@selector(tabForward:)];
UIKeyCommand *const backward = [UIKeyCommand keyCommandWithInput:@"\t" modifierFlags:UIKeyModifierShift action:@selector(tabBackward:)];
commands = @[forward, backward];
});
return commands;
}
- (void)tabForward:(UIKeyCommand *)command
{
NSArray *const controls = self.controls;
UIResponder *firstResponder = nil;
for (UIResponder *const responder in controls) {
if (firstResponder != nil && responder.canBecomeFirstResponder) {
[responder becomeFirstResponder]; return;
}
else if (responder.isFirstResponder) {
firstResponder = responder;
}
}
[controls.firstObject becomeFirstResponder];
}
- (void)tabBackward:(UIKeyCommand *)command
{
NSArray *const controls = self.controls;
UIResponder *firstResponder = nil;
for (UIResponder *const responder in controls.reverseObjectEnumerator) {
if (firstResponder != nil && responder.canBecomeFirstResponder) {
[responder becomeFirstResponder]; return;
}
else if (responder.isFirstResponder) {
firstResponder = responder;
}
}
[controls.lastObject becomeFirstResponder];
}
Es kann eine zusätzliche Logik für das Scrollen von zuvor sichtbaren Offscreen-Respondern gelten.
Ein weiterer Vorteil dieses Ansatzes ist, dass Sie nicht alle Arten von Steuerelementen, die Sie möglicherweise anzeigen möchten, unterklassifizieren müssen (wie UITextField
s), sondern kann stattdessen die Logik auf Controller-Ebene verwalten, wo, seien wir ehrlich, die der richtige Ort zu tun.