Ich habe eine UITableView
mit 5 UITableViewCells
. Jede Zelle enthält eine, UIButton
die wie folgt eingerichtet ist:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:1];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell viewWithTag:1];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
Meine Frage lautet: buttonPressedAction:
Woher weiß ich bei der Methode, welche Taste gedrückt wurde? Ich habe überlegt, Tags zu verwenden, bin mir aber nicht sicher, ob dies der beste Weg ist. Ich möchte das irgendwie indexPath
auf dem Steuerelement markieren können.
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
// how do I know which button sent this message?
// processing button press for this row requires an indexPath.
}
Was ist der Standard dafür?
Bearbeiten:
Ich habe es irgendwie gelöst, indem ich Folgendes getan habe. Ich würde immer noch gerne eine Meinung dazu haben, ob dies die Standardmethode ist oder ob es eine bessere gibt.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell.contentView.subviews objectAtIndex:0];
[button setTag:indexPath.row];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
int row = button.tag;
}
Es ist wichtig zu beachten, dass ich das Tag bei der Erstellung der Zelle nicht festlegen kann, da die Zelle stattdessen möglicherweise aus der Warteschlange entfernt wird. Es fühlt sich sehr schmutzig an. Es muss einen besseren Weg geben.
quelle
Antworten:
Im Apple Accessory- Beispiel wird die folgende Methode verwendet:
Anschließend wird im Touch-Handler die Touch-Koordinate abgerufen und der Indexpfad aus dieser Koordinate berechnet:
quelle
Ich fand, dass die Methode, die Superview der Superview zu verwenden, um einen Verweis auf den indexPath der Zelle zu erhalten, perfekt funktionierte. Vielen Dank an iphonedevbook.com (macnsmith) für den Tipp- Link-Text
quelle
Hier ist, wie ich es mache. Einfach und prägnant:
quelle
CGPointZero
anstelle vonCGPointMake(0, 0)
;-)Ich habe an anderer Stelle eine gute Lösung für dieses Problem gefunden, ohne mit Tags auf der Schaltfläche herumzuspielen:
quelle
buttonPressedAction:
aberbuttonPressedAction:forEvent:
.Wie wäre es mit dem Senden der Informationen wie
NSIndexPath
in derUIButton
Verwendung der Laufzeitinjektion.1) Sie benötigen Laufzeit für den Import
2) statische Konstante hinzufügen
3) Fügen Sie
NSIndexPath
Ihrer Schaltfläche zur Laufzeit Folgendes hinzu:(void) setMetaData: (id) Ziel withObject: (id) newObj
4) Beim Drücken der Taste erhalten Sie Metadaten mit:
(id) metaData: (id) Ziel
Genießen
quelle
Die Antwort von To (@Vladimir) lautet Swift:
Obwohl das Überprüfen nach
indexPath != nil
mir den Finger gibt ... "NSIndexPath ist kein Subtyp von NSString"quelle
Mit Swift 4.2 und iOS 12 können Sie eines der 5 folgenden vollständigen Beispiele auswählen , um Ihr Problem zu lösen.
# 1. Verwenden von
UIView
'sconvert(_:to:)
undUITableView
' sindexPathForRow(at:)
# 2. Verwenden von
UIView
'sconvert(_:to:)
undUITableView
' sindexPathForRow(at:)
(Alternative)Dies ist eine Alternative zum vorherigen Beispiel, in dem wir
nil
an dentarget
Parameter in übergebenaddTarget(_:action:for:)
. Auf diese Weise wird der erste Antwortende, der die Aktion nicht implementiert, an den nächsten Antwortenden in der Antworterkette gesendet, bis eine ordnungsgemäße Implementierung gefunden wurde.#3. Verwenden von
UITableView
'sindexPath(for:)
und delegieren MusterIn diesem Beispiel legen wir den Ansichtscontroller als Delegaten der Zelle fest. Wenn Sie auf die Schaltfläche der Zelle tippen, wird die entsprechende Methode des Delegaten aufgerufen.
# 4. Verwenden von
UITableView
'sindexPath(for:)
und einem Abschluss für die DelegationDies ist eine Alternative zum vorherigen Beispiel, bei dem anstelle einer Protokolldelegatdeklaration ein Abschluss verwendet wird, um das Tippen auf die Schaltfläche zu handhaben.
# 5. Verwenden von
UITableViewCell
'saccessoryType
undUITableViewDelegate
' stableView(_:accessoryButtonTappedForRowWith:)
Wenn Ihre Taste ist ein
UITableViewCell
‚s Standardzubehör Kontrolle, jeder Hahn an wird es einen Anruf auslösenUITableViewDelegate
s‘tableView(_:accessoryButtonTappedForRowWith:)
, so dass Sie die damit verbundenen Indexpfad erhalten.quelle
quelle
Ich würde die Tag-Eigenschaft wie gesagt verwenden und das Tag so einstellen:
Dann wird das Tag wie folgt in die buttonPressedAction eingefügt:
Oder
quelle
tag
ist eine ganze Zahl. Es scheint etwas ungeschickt zu sein, Indexpfade in Ansichts-Tags zu codieren / decodieren.Obwohl mir die Tag-Methode gefällt ... Wenn Sie aus irgendeinem Grund keine Tags verwenden möchten, können Sie ein Mitglied
NSArray
mit vorgefertigten Schaltflächen erstellen :Erstellen Sie dann diese Schaltflächen, bevor Sie die tableView rendern, und verschieben Sie sie in das Array.
Innerhalb der
tableView:cellForRowAtIndexPath:
Funktion können Sie dann Folgendes tun:Dann können Sie in der
buttonPressedAction:
Funktion tunquelle
ABSCHNITTE BEHANDELN - Ich habe den NSIndexPath in einer benutzerdefinierten UITableViewCell gespeichert
IN CLKIndexPricesHEADERTableViewCell.xib
IN IB UIButton zu XIB hinzufügen - Aktion NICHT hinzufügen!
Add outlet @property (beibehalten, nicht atomar) IBOutlet UIButton * buttonIndexSectionClose;
NICHT STRG + DRAG eine Aktion in IB (im Code unten ausgeführt)
In viewForHeaderInSection (sollte auch für cellForRow .... etc funktionieren, wenn Ihre Tabelle nur 1 Abschnitt enthält)
... verwenden Sie den Abschnitt, um Daten für Ihre Zelle abzurufen
...Füll es aus
USER drückt die DELETE-Taste in einer Abschnittsüberschrift und dies ruft auf
In diesem Beispiel habe ich eine Schaltfläche zum Löschen hinzugefügt, damit UIAlertView angezeigt wird, um dies zu bestätigen
Ich speichere den Abschnitt und den Schlüssel im Wörterbuch und speichere Informationen über den Abschnitt in einem Ivar im VC
quelle
quelle
Es funktioniert auch bei mir, danke @Cocoanut
Ich fand, dass die Methode, die Superview der Superview zu verwenden, um einen Verweis auf den indexPath der Zelle zu erhalten, perfekt funktionierte. Vielen Dank an iphonedevbook.com (macnsmith) für den Tipp-Link-Text
quelle
Sie können das Tag-Muster verwenden:
quelle
Vermisse ich etwas Können Sie nicht einfach den Absender verwenden, um die Schaltfläche zu identifizieren? Der Absender gibt Ihnen folgende Informationen:
Wenn Sie dann die Eigenschaften der Schaltfläche ändern möchten, sagen Sie das Hintergrundbild, das Sie gerade dem Absender mitteilen:
Wenn Sie das Tag benötigen, ist die Methode von ACBurk in Ordnung.
quelle
Eigentlich ziemlich einfach:
Funktioniert gut für mich: P.
Wenn Sie Ihr Zielaktions-Setup anpassen möchten, können Sie den Ereignisparameter in die Methode aufnehmen und dann die Berührungen dieses Ereignisses verwenden, um die Koordinaten der Berührung aufzulösen. Die Koordinaten müssen noch in den Grenzen der Berührungsansicht aufgelöst werden, aber das scheint für manche Menschen einfacher zu sein.
quelle
Erstellen Sie ein nsmutable-Array und setzen Sie alle Schaltflächen in dieses Array. usint [array addObject: yourButton];
in der Tastendruckmethode
- -
quelle
Eine geringfügige Abweichung von der Antwort von Cocoanuts (die mir bei der Lösung dieses Problems geholfen hat), als sich die Schaltfläche in der Fußzeile einer Tabelle befand (wodurch verhindert wird, dass Sie die angeklickte Zelle finden:
quelle
Ich benutze immer Tags.
Sie müssen die Unterklasse
UITableviewCell
und den Tastendruck von dort aus handhaben.quelle
Es ist einfach; Erstellen Sie eine benutzerdefinierte Zelle und nehmen Sie einen Knopf heraus
Ändern Sie die ID in der obigen Methode in
(UIButton *)
Sie können den Wert ermitteln, auf den die Schaltfläche getippt wird, indem Sie sender.tag ausführen.
quelle
Unterordnen Sie die Schaltfläche, um den erforderlichen Wert zu speichern, und erstellen Sie möglicherweise ein Protokoll (ControlWithData oder ähnliches). Legen Sie den Wert fest, wenn Sie die Schaltfläche zur Tabellenansichtszelle hinzufügen. Überprüfen Sie in Ihrem Ausbesserungsereignis, ob der Absender das Protokoll befolgt, und extrahieren Sie die Daten. Normalerweise speichere ich einen Verweis auf das tatsächliche Objekt, das in der Tabellenansichtszelle gerendert wird.
quelle
SWIFT 2 UPDATE
Hier erfahren Sie, wie Sie herausfinden, auf welche Schaltfläche getippt wurde, und Daten von dieser Schaltfläche an einen anderen ViewController senden,
indexPath.row
da ich davon ausgehe, dass dies der Punkt für die meisten ist!Für diejenigen, die eine ViewController-Klasse verwenden und eine tableView hinzugefügt haben, verwende ich einen ViewController anstelle eines TableViewControllers, sodass ich die tableView manuell hinzugefügt habe, um darauf zuzugreifen.
Hier ist der Code zum Übergeben von Daten an einen anderen VC, wenn Sie auf diese Schaltfläche tippen und die Zelle übergeben
indexPath.row
quelle
Beachten Sie, dass ich hier eine benutzerdefinierte Zelle verwende. Dieser Code funktioniert perfekt für mich
quelle
Chris Schwerdts Lösung hat dann aber in Swift für mich funktioniert:
quelle
Dieses Problem besteht aus zwei Teilen:
1) Abrufen des Indexpfads, der
UITableViewCell
gedrückt enthältUIButton
Es gibt einige Vorschläge wie:
Aktualisierung
UIButton
‚stag
incellForRowAtIndexPath:
Methode Indexpfad des mitrow
Wert. Dies ist keine gute Lösung, da einetag
kontinuierliche Aktualisierung erforderlich ist und nicht mit Tabellenansichten mit mehr als einem Abschnitt funktioniert.Hinzufügen einer
NSIndexPath
Eigenschaft zu einer benutzerdefinierten Zelle und Aktualisieren dieser Eigenschaft anstelle der MethodeUIButton
'stag
in 'cellForRowAtIndexPath:
. Dies löst das Problem mit mehreren Abschnitten, ist aber immer noch nicht gut, da es immer aktualisiert werden muss.Beibehalten einer schwachen Referenz zum übergeordneten Element
UITableView
in der benutzerdefinierten Zelle, während diese erstellt wird, und Verwenden derindexPathForCell:
Methode zum Abrufen des Indexpfads . Scheint ein bisschen besser zu sein, es ist nicht erforderlich, irgendetwas in dercellForRowAtIndexPath:
Methode zu aktualisieren , aber es ist immer noch erforderlich, eine schwache Referenz festzulegen, wenn die benutzerdefinierte Zelle erstellt wird.Verwenden der Zelleigenschaft
superView
, um einen Verweis auf das übergeordnete Element abzurufenUITableView
. Sie müssen der benutzerdefinierten Zelle keine Eigenschaften hinzufügen und müssen bei der Erstellung / später nichts festlegen / aktualisieren. Die ZellensuperView
hängen jedoch von den Details der iOS-Implementierung ab. Es kann also nicht direkt verwendet werden.Dies kann jedoch mit einer einfachen Schleife erreicht werden, da wir sicher sind, dass sich die betreffende Zelle in einer UITableView befinden muss:
Diese Vorschläge können also zu einer einfachen und sicheren benutzerdefinierten Zellenmethode kombiniert werden, um den Indexpfad abzurufen:
Von nun an kann mit dieser Methode erkannt werden, welche
UIButton
gedrückt wird.2) Informieren anderer Parteien über das Drücken von Tasten
Nachdem intern bekannt ist, welche
UIButton
in welcher benutzerdefinierten Zelle mit genauem Indexpfad gedrückt wird, müssen diese Informationen an andere Parteien gesendet werden (höchstwahrscheinlich an den View Controller, der die verwaltetUITableView
). Daher kann dieses Schaltflächenklickereignis in einer ähnlichen Abstraktions- unddidSelectRowAtIndexPath:
Logikebene wie die Methode des UITableView-Delegaten behandelt werden.Hierfür können zwei Ansätze verwendet werden:
a) Delegierung: Benutzerdefinierte Zellen können eine
delegate
Eigenschaft haben und ein Protokoll definieren. Wenn die Taste gedrückt wird, werden nur die Delegierungsmethoden für diedelegate
Eigenschaft ausgeführt. Diesedelegate
Eigenschaft muss jedoch für jede benutzerdefinierte Zelle festgelegt werden, wenn sie erstellt wird. Alternativ kann eine benutzerdefinierte Zelle ihre Delegierungsmethoden auch für die übergeordnete Tabellenansicht ausführendelegate
.b) Benachrichtigungscenter: Benutzerdefinierte Zellen können einen benutzerdefinierten Benachrichtigungsnamen definieren und diese Benachrichtigung mit den im
userInfo
Objekt bereitgestellten Indexpfad- und übergeordneten Tabellenansichtsinformationen veröffentlichen . Es ist nicht erforderlich, für jede Zelle etwas festzulegen. Es reicht aus, nur einen Beobachter für die Benachrichtigung der benutzerdefinierten Zelle hinzuzufügen.quelle
Ich verwende eine Lösung dieser Unterklasse
UIButton
und dachte, ich sollte sie hier nur teilen, Codes in Swift:Denken Sie dann daran, den Indexpfad in zu aktualisieren
cellForRow(at:)
Wenn Sie also auf das Ereignis der Schaltfläche reagieren, können Sie es wie folgt verwenden
quelle