Outlets können nicht mit iOS-Wiederholungsinhalten verbunden werden


144

Ich habe gerade eine App erstellt und angefangen, @ IBOutlets mit dem Storyboard zu verbinden. Ich verbinde einige von ihnen mit Beschriftungen in einer UITableViewCell-Prototypzelle mit einem Basisstil. Wenn ich es verbinde, wird im Storyboard der folgende Fehler angezeigt:

Das detailText Outlet vom TableViewController zum UILabel ist ungültig. Outlets können nicht mit sich wiederholenden Inhalten verbunden werden.

Kann mir jemand helfen? Ich habe es so eingerichtet, wie ich es immer erfolgreich gemacht habe, aber dieses Mal hat es mir diesen Fehler beschert.


54
Sie können ein Etikett in einer Prototypzelle nicht mit einem IBOutlet in einer UIViewController-Unterklasse verbinden. Sie müssen es mit einem IBOutlet in einer UITableviewCell-Unterklasse verbinden.
Paulw11

OK danke! :) Also nur damit ich verstehe: Kannst du erklären warum?
Tomblasta

3
Da Sie eine beliebige Anzahl von Zellen und nur einen einzigen Ansichtscontroller haben können - welche Zellenbezeichnung sollte also mit dem IBOutlet des Ansichtscontrollers verbunden werden?
Paulw11

Ok, warum konnten Sie den cellForRowAtIndexPath nicht einfach für den Zellentext in einem einzigen Ansichts-Controller verwenden? Vielen Dank!
Tomblasta

3
Da Steckdosen beim Laden des Ansichts-Controllers an Objekte (z. B. Beschriftungen) gebunden sind - Zu diesem Zeitpunkt gibt es keine Zellen, also keine Beschriftung zum Binden, und wenn es Zellen gab, welche wollten Sie binden
Paulw11

Antworten:


168

Erstellen Sie eine Unterklasse für Tabellenansichtszellen und legen Sie sie als Klasse des Prototyps fest. Fügen Sie die Steckdosen dieser Klasse hinzu und verbinden Sie sie. Wenn Sie nun die Zelle konfigurieren, können Sie auf die Steckdosen zugreifen.


9
@Wain können Sie bitte weitere Informationen zum Zugang zu diesen Verkaufsstellen hinzufügen?
Juan Boero

1
Juan Pablo - Was er sagt ist, dass es normal ist, eine benutzerdefinierte Tabellenansichtszelle zu verwenden. Sie können den Ausgang für eine Einschränkung nicht in der Ansicht festlegen, in der Sie die Zelle verwenden. Stattdessen müssen Sie dies beispielsweise in cellForRowAtIndexPath tun - customCell.constraint_row_width.constant = 25.0;
Stuart P.

70

Es gibt zwei Arten von Tabellenansichtszellen, die Ihnen über das Storyboard zur Verfügung gestellt werden: dynamische Prototypen und statische Zellen

Geben Sie hier die Bildbeschreibung ein

1. Dynamische Prototypen

Aus dem Namen wird dieser Zelltyp dynamisch generiert. Sie werden über Ihren Code gesteuert, nicht über das Storyboard. Mithilfe des Delegaten und der Datenquelle der Tabellenansicht können Sie die Anzahl der Zellen, die Höhe der Zellen und den Prototyp der Zellen programmgesteuert angeben.

Wenn Sie eine Zelle in Ihre Tabellenansicht ziehen, deklarieren Sie einen Prototyp von Zellen. Sie können dann eine beliebige Anzahl von Zellen erstellen, die auf diesem Prototyp basieren, und diese cellForRowprogrammgesteuert über die Methode zur Tabellenansicht hinzufügen . Dies hat den Vorteil, dass Sie nur einen Prototyp definieren müssen, anstatt jede einzelne Zelle mit allen Ansichten zu erstellen, die Sie selbst hinzugefügt haben (siehe statische Zelle).

In diesem Fall können Sie keine UI-Elemente auf dem Zellenprototyp mit Ihrem View Controller verbinden. Sie haben nur ein View Controller-Objekt initiiert, aber möglicherweise haben Sie viele Zellenobjekte initiiert und zu Ihrer Tabellenansicht hinzugefügt. Es ist nicht sinnvoll, den Zellenprototyp mit dem View Controller zu verbinden, da Sie nicht mehrere Zellen mit einer View Controller-Verbindung steuern können. Und Sie werden eine Fehlermeldung erhalten, wenn Sie dies tun.

Geben Sie hier die Bildbeschreibung ein

Um dieses Problem zu beheben, müssen Sie Ihr Prototypetikett mit einem UITableViewCellObjekt verbinden. A UITableViewCellist auch ein Prototyp von Zellen, und Sie können so viele Zellenobjekte initiieren, wie Sie möchten. Jedes von ihnen wird dann mit einer Ansicht verbunden, die aus Ihrem Storyboard-Tabellenzellenprototyp generiert wird.

Geben Sie hier die Bildbeschreibung ein

Schließlich in Ihrer cellForRowMethode erstellen aus der die benutzerdefinierten Zelle UITableViewCellKlasse und macht lustige Sachen mit dem Etikett

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "yourCellIdentifier") as! YourCell

    cell.label.text = "it works!"

    return cell
}

2. Statische Zellen

Andererseits werden statische Zellen tatsächlich über das Storyboard konfiguriert. Sie müssen UI-Elemente in jede einzelne Zelle ziehen, um sie zu erstellen. Sie steuern die Zellennummern, -höhen usw. über das Storyboard. In diesem Fall wird eine Tabellenansicht angezeigt, die auf Ihrem Telefon genau dieselbe ist wie auf dem Storyboard. Statische Zellen werden häufiger zum Einstellen von Seiten verwendet, wobei sich die Zellen nicht stark ändern.

Um UI-Elemente für eine statische Zelle zu steuern, müssen Sie sie tatsächlich direkt mit Ihrem View Controller verbinden und einrichten.

Geben Sie hier die Bildbeschreibung ein


@ FangmingNing in meinem Code, ich kann immer noch nicht Textbeschriftung ändern, ich habe Klasse mit Zelle verbunden, korrekte Zelle mit Kennung genannt, aber immer noch nicht ändern
Jorge Saraiva

@jorgesaraiva Lassen Sie uns dies im Chatraum diskutieren chat.stackoverflow.com/rooms/159396/discuss
Fangming

Ich wurde vermisst als! YourCell . +100
Daniel Springer

Es ist immer gut, eine kleine Auffrischung zu haben, nachdem Sie 6 Monate lang an einem Projekt in nur Code gearbeitet haben.
Ttorbik

Vielen Dank, mein Problem ist, dass ich es eher mit dem ViewController als mit der Zelle verbinde.
Stella

23

Wenn Sie eine Tabelle im Hinblick auf Display - Einstellungen und andere Optionen verwenden (wie die eingebauten Einstellungen App der Fall ist), dann können Sie Ihr Set Tabellenansicht Inhalt zu Static Cells unter der Inspektor Attribute . Dazu müssen Sie Ihre Tabellenansicht in eine UITableViewController-Instanz einbetten.


Dies ist viel einfacher und schneller und sollte die akzeptierte Antwort imho sein
Jaime Agudo

5

Oder Sie müssen IBOutlet nicht verwenden , um auf das Objekt in der Ansicht zu verweisen. Sie können dem Label in der tableViewCell einen Tag-Wert geben, z. B. das Tag auf 123 setzen (dies kann vom Attributinspektor durchgeführt werden). Dann können Sie über auf das Etikett zugreifen

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "someID", for: indexPath)

    let label = cell.viewWithTag(123) as! UILabel //refer the label by Tag

    switch indexPath.row {
    case 0:
        label.text = "Hello World!"
    default:
        label.text = "Default"
    }
    return cell 
}

sehr einfach und unkompliziert! +100
Julian Silvestri

1

Bei mir habe ich eine UIViewcontroller, und darin habe ich eine Tabellenansicht mit einer benutzerdefinierten Zelle. Ich ordne meine UILabel-Steckdose UItableviewcelldem UIViewControllerdann den Fehler zu.


Machen Sie eine benutzerdefinierte Zellenklasse und instanziieren Sie das Iboutlet in Ihrer benutzerdefinierten Klasse
Shauket Sheikh

0

Wie die meisten Leute darauf hingewiesen haben, dass Unterklassen UITableViewCell dieses Problem lösen. Der Grund dafür ist jedoch nicht zulässig, da die Prototypzelle ( UITableViewCell ) von Apple definiert wurde und Sie keine eigenen Steckdosen hinzufügen können.


0

Manchmal konnte Xcode die korrekte Verbindung der Zellensteckdose nicht steuern.

Irgendwie hat das Etikett / die Schaltfläche meiner aktuellen Zelle eine andere Zelle verbunden. Ich entferne diese einfach und der Fehler verschwindet.


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.