Wählen Sie die Tabellenansichtszeile programmgesteuert aus


135

Wie wähle ich programmgesteuert eine UITableViewZeile aus, damit

- (void)tableView:(UITableView *)tableView 
        didSelectRowAtIndexPath:(NSIndexPath *)indexPath

wird hingerichtet? selectRowAtIndexPathhebt nur die Zeile hervor.


Ich bin auf das gleiche Problem gestoßen und habe den Link in Ordnung gebracht : stackoverflow.com/questions/5324501/… Ich hoffe, es wird für Sie hilfreich sein.
Michael

Antworten:


109

Aus der Referenzdokumentation:

Das Aufrufen dieser Methode bewirkt weder, dass der Delegat eine tableView:willSelectRowAtIndexPath:oder eine tableView:didSelectRowAtIndexPath:Nachricht empfängt , noch sendet er UITableViewSelectionDidChangeNotificationBenachrichtigungen an Beobachter.

Was ich tun würde ist:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [self doSomethingWithRowAtIndexPath:indexPath];
}

Und dann, von wo aus Sie selectRowAtIndexPath aufrufen wollten, rufen Sie stattdessen doSomethingWithRowAtIndexPath auf. Darüber hinaus können Sie auch selectRowAtIndexPath aufrufen, wenn das UI-Feedback erfolgen soll.


4
Wenn Sie die Zeile programmgesteuert auswählen, können Sie tableView: didSelectRowAtIndexPath: yourself aufrufen (in der Klasse, die Sie als Delegat verkabelt haben).
Kendall Helmstetter Gelner

3
Diese Methode scheint mir ein Hack zu sein, sie hat den Job erledigt, aber ich denke, es sollte einen besseren Weg geben, dies zu tun.
Tapan Thaker

1
Ich glaube nicht, dass Sie einen Aufruf "doSomethingWithRowAtIndexPath" erstellen müssen. Können Sie nicht einfach die Delegate-Methode aufrufen und die Argumente übergeben, die Sie zum Ausführen der didSelect-Logik von der Stelle aus benötigen, an der Sie die Delegate-Methode implementiert haben?
ImpactZero

111

Wie Jaanus sagte:

Wenn Sie diese Methode (-selectRowAtIndexPath: animiert: scrollPosition :) aufrufen, erhält der Delegat keine tableView: willSelectRowAtIndexPath: - oder tableView: didSelectRowAtIndexPath: -Nachricht und sendet keine UITableViewSelectionDidChangeNotification-Benachrichtigungen.

Sie müssen die delegateMethode also nur selbst aufrufen .

Beispielsweise:

Swift 3 Version:

let indexPath = IndexPath(row: 0, section: 0);
self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)
self.tableView(self.tableView, didSelectRowAt: indexPath)

ObjectiveC-Version:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView selectRowAtIndexPath:indexPath 
                            animated:YES 
                      scrollPosition:UITableViewScrollPositionNone];
[self tableView:self.tableView didSelectRowAtIndexPath:indexPath];

Swift 2.3 Version:

 let indexPath = NSIndexPath(forRow: 0, inSection: 0);
 self.tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.None)
 self.tableView(self.tableView, didSelectRowAtIndexPath: indexPath)

63

SelectRowAtIndexPath von UITableView: animiert: scrollPosition: sollte den Trick machen.

UITableViewScrollPositionNoneÜbergeben Sie einfach scrollPosition und der Benutzer sieht keine Bewegung.


Sie sollten die Aktion auch manuell ausführen können:

[theTableView.delegate tableView:theTableView didSelectRowAtIndexPath:indexPath]

Nach Ihnen selectRowAtIndexPath:animated:scrollPosition:geschieht das Highlight ebenso wie die zugehörige Logik.


Entschuldigung, das ist was ich benutze. Ich habe versehentlich scrollToRowAtIndexPath eingefügt. Ich habe die Frage aktualisiert. scrollToRowAtIndexPath hebt nur die Zelle hervor.
4thSpace

2
Ja, tut mir leid. Es heißt, dass didSelectRowAtIndexPath nicht genau dort im von mir geposteten Dokumentlink ausgelöst wird. Ich muss lesen lernen.
Anq

@anq: Vielen Dank! Es hilft mir, wenn ich didSelectRowAtIndexPath: indexPath in der benutzerdefinierten Zelle aufrufe.
Bentley

21

Wenn Sie eine Zeile auswählen möchten, hilft dies Ihnen

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[someTableView selectRowAtIndexPath:indexPath 
                           animated:NO 
                     scrollPosition:UITableViewScrollPositionNone];

Dadurch wird auch die Zeile hervorgehoben. Dann delegieren

 [someTableView.delegate someTableView didSelectRowAtIndexPath:indexPath];

18

Schnelle 3/4/5 Lösung

Wählen Sie Zeile

let indexPath = IndexPath(row: 0, section: 0)
tblView.selectRow(at: indexPath, animated: true, scrollPosition: .bottom)
myTableView.delegate?.tableView!(myTableView, didSelectRowAt: indexPath)

Zeile abwählen

let deselectIndexPath = IndexPath(row: 7, section: 0)
tblView.deselectRow(at: deselectIndexPath, animated: true)
tblView.delegate?.tableView!(tblView, didDeselectRowAt: indexPath)

Für mich das Hinzufügen von '.delegate?' war der Schlüssel. (Swift 4.5)
KoreanXcodeWorker

4

Es gibt zwei verschiedene Methoden für iPad- und iPhone-Plattformen, daher müssen Sie beide implementieren:

  • Auswahlhandler und
  • Übergang.

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
    
    // Selection handler (for horizontal iPad)
    [self tableView:self.tableView didSelectRowAtIndexPath:indexPath];
    
    // Segue (for iPhone and vertical iPad)
    [self performSegueWithIdentifier:"showDetail" sender:self];

3

Verwenden Sie diese Kategorie, um eine Tabellenzeile auszuwählen und nach einer Verzögerung einen bestimmten Abschnitt auszuführen.
Nennen Sie dies innerhalb Ihrer viewDidAppearMethode:

[tableViewController delayedSelection:withSegueIdentifier:]


@implementation UITableViewController (TLUtils)

-(void)delayedSelection:(NSIndexPath *)idxPath withSegueIdentifier:(NSString *)segueID {
    if (!idxPath) idxPath = [NSIndexPath indexPathForRow:0 inSection:0];                                                                                                                                                                 
    [self performSelector:@selector(selectIndexPath:) withObject:@{@"NSIndexPath": idxPath, @"UIStoryboardSegue": segueID } afterDelay:0];                                                                                               
}

-(void)selectIndexPath:(NSDictionary *)args {
    NSIndexPath *idxPath = args[@"NSIndexPath"];                                                                                                                                                                                         
    [self.tableView selectRowAtIndexPath:idxPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];                                                                                                                            

    if ([self.tableView.delegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)])
        [self.tableView.delegate tableView:self.tableView didSelectRowAtIndexPath:idxPath];                                                                                                                                              

    [self performSegueWithIdentifier:args[@"UIStoryboardSegue"] sender:self];                                                                                                                                                            
}

@end

2
Die Frage hatte nichts mit Segues zu tun.
deleted_user

Ja, ungefähr nichts in Ihrer Antwort bezieht sich auf die Frage
Dulgan

2
Schätzen Sie diese Antwort. Dies funktioniert perfekt, wenn der Benutzer das gleiche Verhalten erzielen möchte, aber Storyboards verwendet.
Bijoy Thangaraj
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.