Array durchsuchen Bedingungen für eine TableView

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Array durchsuchen Bedingungen für eine TableView

    Hallo,

    dieses mal habe ich etwas was mich völlig verwirrt und ich glaube einen riesen Denkfehler zu haben. Also ich möchte aktuell eine Art User-Bereich erstellen der aus einer TableView besteht. In dieser TableView habe ich zwei Zellen konfiguriert. Die erste ist größer als die zweite und dient dazu das Profilbild eines Users in groß anzuzeigen. Die zweite soll sonstige Informationen des Users anzeigen, in dem Fall mehrere Fragen.
    Das was ich hier gemacht habe macht nicht unbedingt Sinn, ist aber der Stand der Dinge von dem wie weit ich bisher gekommen bin. Mein Hauptproblem liegt in der cellForRow-Methode mit dem if-Statement.
    Aktuell habe ich vier User in meinem Array wie ihr sehen könnt. Mein Problem mit dem if-Statement ist das ich es zwar schaffe in der ersten "großen" Zelle zwar das Profilbild von Max Mustermann anzuzeigen, in den darauffolgenden Zellen aber alle anderen User angezeigt werden obwohl nur Max Mustermanns Daten zu sehen sein sollen.
    Warum das passiert ist mir auch klar und zwar durch das else-Statement welches alle anderen User mit einer anderen ID als 1 "ausließt".

    Jetzt die Frage wie ich es schaffe auch in der zweiten Zelle nur die Informationen des Users mit der ID 1 anzuzeigen ?
    An sich ist das ja keine große Sache, mir macht nur dir heightForRowAt-Methode einen Strich durch die Rechnung da jeder User mit einer ID von 1, als große Zelle angezeigt wird.
    Die große Zelle soll jedoch nur einmal existieren...

    Ich hoffe ihr versteht mein Problem und könnt mir weiterhelfen, würde mich über jeden Tipp freuen da ich hier so langsam nicht mehr weiß wo oben und unten ist haha.

    Quellcode

    1. var users: [User] = [
    2. User(userID: 1, profilePicture: "bild_user29Lifestyle" ,name: "Max Mustermann", question: "Was findet ihr am besten ?" ),
    3. User(userID: 2, profilePicture: "bild_user29Lifestyle1", name: "Da Vinci", question: "Links oder Rechts ?"),
    4. User(userID: 3, profilePicture: "bild_user29Lifestyle2-1", name: "Travis Scott", question: "Welches Cover ?"),
    5. User(userID: 1, profilePicture: "bild_user30Politik", name: "Max Mustermann", question: "Ihr entscheidet")
    6. ]


    Quellcode

    1. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    2. if users[indexPath.row].userID == 1 {
    3. let cell = tableView.dequeueReusableCell(withIdentifier: "UserLine", for: indexPath) as! TappedImageTableViewCell
    4. let user = users[indexPath.row]
    5. let image = UIImage(named: user.profilePicture)
    6. cell.profileImage.image = image
    7. cell.profileImage.layer.cornerRadius = cell.profileImage.frame.width / 2;
    8. cell.profileImage.layer.borderWidth = 1
    9. cell.profileImage.layer.borderColor = UIColor.lightGray.cgColor
    10. cell.profileImage.layer.masksToBounds = true
    11. return cell
    12. } else {
    13. let cell = tableView.dequeueReusableCell(withIdentifier: "QuestionLine", for: indexPath) as! UserTableViewCell
    14. let user = users[indexPath.row]
    15. cell.titleLabel.text = user.question
    16. cell.detailLabel.text = user.name
    17. let image = UIImage(named: user.profilePicture)
    18. cell.imageV.image = image
    19. cell.imageV.layer.cornerRadius = cell.imageV.frame.width / 2;
    20. cell.imageV.layer.borderWidth = 1
    21. cell.imageV.layer.borderColor = UIColor.lightGray.cgColor
    22. cell.imageV.layer.masksToBounds = true
    23. return cell
    24. }
    25. }
    Alles anzeigen

    Quellcode

    1. override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    2. if users[indexPath.row].userID == 1 {
    3. return 269.0
    4. } else {
    5. return 80.0
    6. }
    7. }

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ThisIsBeat ()

  • Da scheint mit grundsätzlich konzeptionell etwas falsch zu laufen bei Deinem Gedankenansatz, speziell was das Verständnis von Indices und IDs angeht. o_O

    1.) IDs dienen dazu, ein Element eindeutig zu kennzeichnen. Sie dienen nicht dazu, anzugeben an welcher Stelle einer Liste sie stehen. Stell Dir vor, Du filterst Deine User nach dem Anfangsbuchstaben 'S' des Nachnamens und sortierts sie aufsteigend. Deren ID und der Platz, wo sie in der Tabelle angezeigt werden, hat dann nichts mehr miteinander zu tun.

    2.) IDs werden nicht von der Call-Site vergeben. Warum sieht man in Deinem Code. ;)

    ThisIsBeat schrieb:

    Quellcode

    1. var users: [User] = [
    2. User(userID: 1, profilePicture: "bild_user29Lifestyle" ,name: "Max Mustermann", question: "Was findet ihr am besten ?" ),
    3. User(userID: 2, profilePicture: "bild_user29Lifestyle1", name: "Da Vinci", question: "Links oder Rechts ?"),
    4. User(userID: 3, profilePicture: "bild_user29Lifestyle2-1", name: "Travis Scott", question: "Welches Cover ?"),
    5. User(userID: 1, profilePicture: "bild_user30Politik", name: "Max Mustermann", question: "Ihr entscheidet")
    6. ]

    Die User-ID 1 ist zweimal vergeben. IDs werden entweder von einem Managmentsystem vergeben, wie z.B. einer Datenbank, oder aber automatisch als UUID vom Typ. Stell Dir vor Du könntest Dir bei Amazon oder so Deine eigene Kundennummer vergeben. Wär das ein Chaos! :D

    Also, ich würde das zuerst angehen und mich dann um die Darstellung im Table-View kümmern…^^
    Twix heißt jetzt Raider!
  • torquato schrieb:

    Da scheint mit grundsätzlich konzeptionell etwas falsch zu laufen bei Deinem Gedankenansatz, speziell was das Verständnis von Indices und IDs angeht. o_O

    1.) IDs dienen dazu, ein Element eindeutig zu kennzeichnen. Sie dienen nicht dazu, anzugeben an welcher Stelle einer Liste sie stehen. Stell Dir vor, Du filterst Deine User nach dem Anfangsbuchstaben 'S' des Nachnamens und sortierts sie aufsteigend. Deren ID und der Platz, wo sie in der Tabelle angezeigt werden, hat dann nichts mehr miteinander zu tun.

    2.) IDs werden nicht von der Call-Site vergeben. Warum sieht man in Deinem Code. ;)

    Die User-ID 1 ist zweimal vergeben. IDs werden entweder von einem Managmentsystem vergeben, wie z.B. einer Datenbank, oder aber automatisch als UUID vom Typ. Stell Dir vor Du könntest Dir bei Amazon oder so Deine eigene Kundennummer vergeben. Wär das ein Chaos! :D

    Also, ich würde das zuerst angehen und mich dann um die Darstellung im Table-View kümmern…^^
    Hey :)

    zu 1. :
    Genau daran liegt es ja gerade. Mir ist klar das dass es äußerst ungünstig ist über die ID eine Zuweisung zu erstellen. Deswegen suche ich ja nach einer Möglichkeit wie ich Informationen EINES Users, auf die zwei unterschiedlichen Zellen zuteile. Aktuell läuft die Zuteilung ja über das if else Prinzip was absolut unpassend an der Stelle ist.

    zu 1, 2 und dem Rest :
    also ist mir alles schon klar, aber aktuell arbeite ich noch ohne eine Datenbank was bedeutet das ich das ganze irgendwie simulieren muss. Das in dem Array also der User zwei mal mit der selben ID vorkommt ist demnach so gewollt von mir da das auch in der Datenbank vorkommen kann und wird. Irgendwann nehme ich mir noch vor einem User bei der Registrierung bereits eine ID zuzuweisen nur wie gesagt, aktuell muss ich das zu Testzwecken noch anders lösen.
  • Okay also ich habe jetzt einfach mal weiter rum experimentiert und das mit den Sections ausprobiert was recht interessant ausschaut. Doch leider habe ich damit zwei Probleme :/

    Einmal mit numberOfRowsInSection. Hier sollen ja in QuestionLine (Hat den section Index 1) nur die Fragen des Users mit der ID 1 angezeigt werden. Über eine for-in-Schleife geht es leider nicht. Das heißt also ich weiß nicht wie ich nur die User zähle die die ID 1 haben....

    Mein zweites Problem liegt im else-Statement der cellForRowAt-Methode. Eigentlich erwarte ich das mir alle User angezeigt werden die eine ID von 1 haben. Mir werden auch zwei User angezeigt, nur leider sind diese identisch. Das heißt es wird zwei mal "Was findet ihr am besten ausgelesen"...

    Bin mir nicht sicher ob ich diesen Ansatz weiter verfolgen sollte oder es doch einen anderen Schlüssel gibt. Hoffe aber das ihr mir irgendwie weiterhelfen könnt :)

    Quellcode

    1. var users: [User] = [
    2. User(userID: 1, profilePicture: "bild_user29Lifestyle" ,name: "Max Mustermann", question: "Was findet ihr am besten ?" ),
    3. User(userID: 2, profilePicture: "bild_user29Lifestyle1", name: "Da Vinci", question: "Links oder Rechts ?"),
    4. User(userID: 3, profilePicture: "bild_user29Lifestyle2-1", name: "Travis Scott", question: "Welches Cover ?"),
    5. User(userID: 1, profilePicture: "bild_user30Politik", name: "Max Mustermann", question: "Ihr entscheidet")
    6. ]

    Quellcode

    1. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    2. if section == 0 {
    3. return 1
    4. } else {
    5. return users.count
    6. }
    7. }
    8. override func numberOfSections(in tableView: UITableView) -> Int {
    9. return 2
    10. }

    Quellcode

    1. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    2. if indexPath.section == 0 {
    3. for user in users where users[indexPath.row].userID == 1 {
    4. let cell = tableView.dequeueReusableCell(withIdentifier: "UserLine", for: indexPath) as! TappedImageTableViewCell
    5. let image = UIImage(named: user.profilePicture)
    6. cell.profileImage.image = image
    7. cell.profileImage.layer.cornerRadius = cell.profileImage.frame.width / 2;
    8. cell.profileImage.layer.borderWidth = 1
    9. cell.profileImage.layer.borderColor = UIColor.lightGray.cgColor
    10. cell.profileImage.layer.masksToBounds = true
    11. return cell
    12. }
    13. } else {
    14. for user in users where users[indexPath.row].userID == 1 {
    15. let cell = tableView.dequeueReusableCell(withIdentifier: "QuestionLine", for: indexPath) as! UserTableViewCell
    16. cell.titleLabel.text = user.question
    17. cell.detailLabel.text = user.name
    18. let image = UIImage(named: user.profilePicture)
    19. cell.imageV.image = image
    20. cell.imageV.layer.cornerRadius = cell.imageV.frame.width / 2;
    21. cell.imageV.layer.borderWidth = 1
    22. cell.imageV.layer.borderColor = UIColor.lightGray.cgColor
    23. cell.imageV.layer.masksToBounds = true
    24. return cell
    25. }
    26. }
    27. return UITableViewCell()
    28. }
    Alles anzeigen

    Quellcode

    1. override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    2. if indexPath.section == 0 {
    3. return 269.0
    4. } else {
    5. return 80.0
    6. }
    7. }
  • Für mich sieht es langsam nach einem Problem in Deinem Datenmodell bzw. einem Verständnisproblems Deines eigenen Datenmodells aus.

    Warum gibt es z.B. zwei Einträge für die userID 1 in dem Array?

    Wie sollen die Daten/Info zur userID 1 jetzt genau angezeigt werden? Eine Zeile UserLine und zwei Zeilen QuestionLine direkt untereinander? Dann solltest Du die beiden Einträge zu userID 1 in dem Array auch zusammenführen. ;)

    Anderenfalls ist mir der Aufbau Deines Datenmodells und die daraus resultierende Anzeige in dem TableView nicht wirklich klar. ?(
  • Ich stimme McDan zu, Dein Datenmodell ist das Problem. Du hast Dich durch deinen Platten TableView negativ beeinflussen lassen beim Datenmodell. Klassischer Anfängerfehler ;)
    Du hast zwei Arten von Daten, nicht eine: User und zu einem User gehörige Fragen.

    Erstellle erst mal ein korrektes Datenmodell. Bitte nicht zwei „dumme“ Arrays, sondern etwas, das die Beziehung zueinander auch darstellt, also beispielsweise ein Dictionary mit zwei Ebenen (käme einem JSON-Objekt aus einer späteren Umsetzung via Datenbankservice sehr nahe), oder beispielsweise zwei Entitäten in Core Data, die mittels Relation verknüpft sind. Klassisch wäre: Objekt der Klasse User mit Array mit Objekten der Klasse Fragen. Damit kennt jedes User-Objekt SEINE Fragen und genau so soll es sein („Kapselung“).

    Um die Datenstruktur eines Users für den TableView DANACH „platt“ zurückzuliefern, fügst Du Methoden in Deiner User-Subklasse ein, die User und Fragen, deren Gesamtanzahl, deren Eigenschaft (User oder Fragen) zurückgibt, ganz so wie es das TableView-Delegate braucht.

    Erst das Datenmodell richtig machen, ganz unabhängig, wie Du die Daten darstellst, sondern einfach so, wie sie zueinander in Beziehung stehen. Dann denkst Du den View. Erst danach fügst Du Methoden ein, die das Ganze zusammenbringen. Letzteres ist am elegantesten direkt in einem Datenobjekt, z. B. simple Zusatzfunktionen im User-Objekt selbst: wie viele Fragen ein User enthält, User mit Fragen als Plattes Array von User-und Fragen-Objekten, usw. so hast Du alles perfekt gekapselt, Deine Objekte werden immer schlauer und du brauchst diese von außen (für den TableView) nur „befragen“, indem Du diese Zusatzfunktionen benutzt.

    LG Norbert
  • norbi schrieb:

    Ich stimme McDan zu, Dein Datenmodell ist das Problem. Du hast Dich durch deinen Platten TableView negativ beeinflussen lassen beim Datenmodell. Klassischer Anfängerfehler ;)
    Du hast zwei Arten von Daten, nicht eine: User und zu einem User gehörige Fragen.

    Erstellle erst mal ein korrektes Datenmodell. Bitte nicht zwei „dumme“ Arrays, sondern etwas, das die Beziehung zueinander auch darstellt, also beispielsweise ein Dictionary mit zwei Ebenen (käme einem JSON-Objekt aus einer späteren Umsetzung via Datenbankservice sehr nahe), oder beispielsweise zwei Entitäten in Core Data, die mittels Relation verknüpft sind. Klassisch wäre: Objekt der Klasse User mit Array mit Objekten der Klasse Fragen. Damit kennt jedes User-Objekt SEINE Fragen und genau so soll es sein („Kapselung“).

    Um die Datenstruktur eines Users für den TableView DANACH „platt“ zurückzuliefern, fügst Du Methoden in Deiner User-Subklasse ein, die User und Fragen, deren Gesamtanzahl, deren Eigenschaft (User oder Fragen) zurückgibt, ganz so wie es das TableView-Delegate braucht.

    Erst das Datenmodell richtig machen, ganz unabhängig, wie Du die Daten darstellst, sondern einfach so, wie sie zueinander in Beziehung stehen. Dann denkst Du den View. Erst danach fügst Du Methoden ein, die das Ganze zusammenbringen. Letzteres ist am elegantesten direkt in einem Datenobjekt, z. B. simple Zusatzfunktionen im User-Objekt selbst: wie viele Fragen ein User enthält, User mit Fragen als Plattes Array von User-und Fragen-Objekten, usw. so hast Du alles perfekt gekapselt, Deine Objekte werden immer schlauer und du brauchst diese von außen (für den TableView) nur „befragen“, indem Du diese Zusatzfunktionen benutzt.

    LG Norbert
    Also ich glaube ich versteh ganz gut was ich da vor habe und ich glaube @MCDans Beitrag hat mich auch auf eine Idee gebracht und zwar könnte man doch das Array filtern nach einem bestimmten User und die gefilterten Daten in ein neues Array schreiben in dem sich dann nur die Infos des gefilterten Users befinden ? Weiß nicht in wie fern das ne gute Idee ist aber kam mir gerade in den Sinn.

    So dann habe ich auch noch ein paar Verständnis Fragen an dich @norbi. Grundsätzlich glaube ich zu verstehen was dein Gedanke ist, doch wie du schon bemerkt hast bin ich noch Anfänger in Swift.

    Sagen wir ich habe ein Dictionary mit verschiedenen Usern als key. Würde der Wert zu den jeweiligen Usern dann ein Array sein in dem die jeweiligen Informationen gespeichert sind ?

    Das klassische Beispiel von dir verwirrt mich eher. Ich verstehe nicht wie dadurch klar sein soll welcher User welche Fragen gestellt hat. Hast du eventuell ein Beispiel oder einen Link an dem deutlich wird wie du das ganze meinst ?
  • Also ich sitze jetzt schon die ganze Zeit vor dem Problem und komme einfach nicht weiter. Nochmal um klar zu stellen was ich eigentlich vor habe. Ich habe eine TableView mit zwei unterschiedlich großen Zellen konfiguriert.
    Da ich aktuell ohne Datenbank arbeite, versuche ich User mit unterschiedlichen Fragen zu simulieren. Diese User befinden sich in einem Array. Da in einer Datenbank pro neuer Frage einer neuer Eintrag vorgenommen werden würde, habe ich in dem Array auch zwei mal ein und den selben User drin der zwei unterschiedliche Sachen fragt.

    Meine TableView soll so etwas wie ein User-Bereich werden in dem der User sein Profilbild, so wie all seine gestellten Fragen sieht.
    Mein Hauptproblem besteht nun darin aus dem Pool an Usern, diejenigen herauszufiltern die ein und die selbe ID haben.

    Mit der ersten Zelle in dem das Profilbild zu sehen ist, habe ich keine Probleme. In der zweiten Zelle in der alle Fragendes Users zu sehen sein sollen
    wird mir leider allerdings für jeden User im Array eine Zelle angezeigt. Und ich verstehe einfach nicht warum...

    Hier der Code:

    Quellcode

    1. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    2. if indexPath.section == 0 {
    3. let cell = tableView.dequeueReusableCell(withIdentifier: "UserLine", for: indexPath) as! TappedImageTableViewCell
    4. for user in users where user.userID == 1 {
    5. let image = UIImage(named: user.profilePicture)
    6. cell.profileImage.image = image
    7. cell.profileImage.layer.cornerRadius = cell.profileImage.frame.width / 2;
    8. cell.profileImage.layer.borderWidth = 1
    9. cell.profileImage.layer.borderColor = UIColor.lightGray.cgColor
    10. cell.profileImage.layer.masksToBounds = true
    11. }
    12. return cell
    13. } else if users[indexPath.row].userID == 1 {
    14. let cell = tableView.dequeueReusableCell(withIdentifier: "QuestionLine", for: indexPath) as! UserTableViewCell
    15. let user = users[indexPath.row]
    16. cell.titleLabel.text = user.question
    17. cell.detailLabel.text = user.name
    18. let image = UIImage(named: user.profilePicture)
    19. cell.imageV.image = image
    20. cell.imageV.layer.cornerRadius = cell.imageV.frame.width / 2;
    21. cell.imageV.layer.borderWidth = 1
    22. cell.imageV.layer.borderColor = UIColor.lightGray.cgColor
    23. cell.imageV.layer.masksToBounds = true
    24. return cell
    25. }
    26. return UITableViewCell()
    27. }
    Alles anzeigen
    Ich unterscheide anhand des Section IndexPath was in die erste Zelle gehört und was in die zweite Zelle soll.
    Ich hoffe es ist klar geworden was ich vor habe und wenn nicht bitte ich euch nachzufragen. Ich verzweifle hier so langsam aber sicher nämlich da ich einfach nicht verstehe warum in der zweiten Zelle alle User im Array berücksichtigt werden....

    PS: Ich weiß das ein Array vermutlich nicht die beste Lösung ist um eine Datenbank zu simulieren. Ich habe auch bereits mehrere Dinge ausprobiert um weiter zu kommen nur leider habe ich keine Vorstellung davon wie so etwas aussehen müsste und auch im Netz habe ich nicht viel gefunden was mir weiter hilft.

    @norbi an deinem Beispiel oder Hinweis, bin ich nach wie vor sehr interessiert :D

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ThisIsBeat ()

  • Sollen nur die Daten und Fragen von einem User oder von allen Usern angezeigt werden?

    Wenn nur die Daten und Fragen von einem User angezeigt werden sollen, dann solltest Du ein gefiltertes Array für die Anzeige im TableView verwenden, in dem sich dann nur die Fragen zu dem gewünschten User befinden. ;)

    Du kannst dann entweder 2 Sections (1. Section = User Daten, 2. Section = Fragen des Users) verwenden oder alles in einer Section anzeigen. Wenn Du alles in einer Section anzeigst, dann berechnet sich die Anzahl der Zeilen für den TableView aus der Anzahl der Einträge in dem gefiltertem Array + 1. Hierbei werden dann in der 1. Zeile (row = 0) die User Daten und in den darauffolgenden Zeilen (row = 1 - n) die Fragen angezeigt. Beim Zugriff auf das gefilterte Array für die Fragen musst Du dann 1 beim Index abziehen, also TableView row 1 = Array index 0.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von MCDan ()

  • „Fragen“ eines „Users“:

    Vergiß die Standardklassen (Array, Dict,..) für diese Objekte. Geht zwar, ist aber wenig elegant und wenn Du kapseln willst, musst Du sowieso subclassen. Außerdem ist eigene Klassen zu erstellen eine gute Übung.

    Erstelle zwei Klassen, eine für User, eine für Fragen. Lege Properties in den Klassen an, also z.B. username (String), fragen (z.B. MutableArray), usw.. Letzteres ist ein Array, das die Fragen-Objekte (!), also Instanzen der Klasse Frage im Array hält. So kennt jeder User „seine“ Fragen und du bekommst die Fragen, indem Du eine User-Instanz einfach danach fragst („user.fragen“). Das ist Kapselung. Dämmert es? :) Nix mit Suchen oder einer Filterschleife, sondern VIEL einfacher.

    Dann kannst Du auch im User-Objekt Methoden hinzufügen, die Du brauchst, z. B. (void) „addFrage(fragenObjekt)“ oder (int)fragenAnzahl, was einen ArrayCount der Fragen eines Users zurückgibt. Letzteres kannst Du gut für das TableView brauchen. Auch das ist Kapselung.

    Dein Controller, der Zwischen Daten und TableView vermittelt, kennt die User-Klasse (die importierst Du dort) und kann relativ schlank aus Infos der Userklasse die Delegate-Methoden für den TableView bereitstellen. DAS ist das MVC-Paradigma „Model, View, Controller“. Genau da musst Du hin. Einmal so gemacht gibst du diese saubere Implementierung nie wieder her / kannst dessen Vorteile genießen. MVC immer im Kopf behalten und zuerst nach diesem Prinzip überlegen, was wo hingehört.

    Alles PseudoCode. Bin nich ein alter Objective-C-Hase und mit der Syntax von Swift nicht vertraut.

    Du könntest das Ganze erst mal auch mit CoreData umsetzen. Dort gestaltest Du Deine Entitäten (so heißen die Klassen in Core Data) grafisch und bekommst „gratis“ Persistenz dazu, d.h. Core Data speichert alles für Dich automatisch.

    LG Norbert
  • Hey gute Nachrichten, es klappt durch eure Hilfe so wie ich mir das vorstelle. Es gibt nur eine Kleinigkeit die noch nicht ganz hinhauen will.

    Quellcode

    1. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    2. if segue.identifier == "votingSegue" {
    3. guard
    4. let index = profileTableView.indexPathForSelectedRow?.row,
    5. let destViewController = segue.destination as? VotingViewController
    6. else { return }
    7. destViewController.moveID = index
    8. let information = questions[index]
    9. destViewController.profilePicture = UIImage(named: information.profilePicture)!
    10. destViewController.questionLabelText = information.question
    11. destViewController.titleName = information.name
    12. print("\(index): '\(information.question)'")
    13. }
    14. }
    Alles anzeigen



    Ich kriege für diese Zeile einen Fehler:

    Quellcode

    1. destViewController.questionLabelText = information.question
    Cannot assign value of type '[String]' to type 'String'

    Also ich vermute mal das es am Index von "question" liegt, der nicht vorhanden ist in dieser Methode. Habe auch schon geschaut was man da machen kann bin aber leider nicht fündig geworden. Das Array schaut so aus:


    Quellcode

    1. var questions: [Question] = [
    2. Question(userID: 1, profilePicture: "bild_user29Lifestyle" ,name: "Max Mustermann", question: ["Was findet ihr besser ?", "Links oder Rechts ?", "Ist das cool ?"]),
    3. Question(userID: 2, profilePicture: "bild_user29Lifestyle1", name: "Da Vinci", question: ["Blau oder Weiß ?", "Zimt oder Zucker ?", "Oben oder unten ?"]),
    4. Question(userID: 3, profilePicture: "bild_user29Lifestyle2-1", name: "Travis Scott", question: ["Das oder Das ?", "Früchte oder Gemüse ?", "Welches T-shirt ?"]),
    5. Question(userID: 4, profilePicture: "bild_user29Lifestyle", name: "DJ Bobo", question: ["Ist das gut so ?", "Voll cool oder ?", "Welche Marke ist am besten ?"])
    6. ]
    Wisst ihr was man da machen kann ?


    Würde das ganz gerne noch beheben bevor ich den gesamten Code rein poste um euch zu fragen was ihr davon haltet :)
  • Hallo!

    Was du machen kannst ist offenbar einen festen Index zu verwenden (0, 1 oder 2).
    Teste doch einmal mit 0. Dann sollte es funktionieren, ist aber vom Ergebnis vielleicht noch nicht
    das richtige.

    Du kannst auch zufällig einen der gültigen Werte im Bereich von 0 bis question.count-1 ermitteln.
    Prinzipiell solltest du wissen, welche der Fragen du sehen möchtest. Möglicherweise hat jeder
    User seine Lieblingsfrage oder es soll immer die kommen, die der zuletzt gestellten folgt.
    Dann musst du dir den Index der Frage vermerken (z.B. in Question).

    Grüße
    Marco
  • Oder um es anders auszudrücken: Überlege einmal, welcher Datentyp auf den beiden Seiten der Zuweisung

    destViewController.questionLabelText = information.question

    verwendet wird...

    questionLabelText ist ein String, information.question ist ... ein Array von Strings. Wie soll man das einem String zuweisen? Einfach keinen Index nehmen, kann wohl kaum eine Lösung sein. Wenn es Dir nur um eine Darstellung der User-Fragen geht, könntest Du diese ja mit einem Zeilenumbruch verknüpft in einen String überführen. Oder eben - wie vorgeschlagen - nur eine Frage anzeigen. Oder nicht ein, sondern mehrere Labels verwenden. Oder, oder, oder...

    Überlege Dir am besten vor‘m Coden mal genau, was Du eigentlich willst.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.
  • Also ich habe jetzt alles hinbekommen und es läuft genau so wie ich mir das alles vorstelle. Ich danke jedem für die Tipps und Hilfe, hat mir viel geholfen :D Ich würde gerne wissen was ihr von dem Code haltet den ich geschrieben habe und ob ihr Verbesserungsvorschläge habt.

    Hier der relevante Code an dem ich gearbeitet habe:

    Quellcode

    1. class Question: User {
    2. var question: [String] = []
    3. init(userID: Int, profilePicture: String, name: String, question: [String]) {
    4. self.question = question
    5. super.init(userID: userID, profilePicture: profilePicture, name: name)
    6. }
    7. }
    8. var questions: [Question] = [
    9. Question(userID: 1, profilePicture: "bild_user27" ,name: "Max Mustermann", question: ["Was findet ihr besser ?", "Links oder Rechts ?", "Ist das cool ?"]),
    10. Question(userID: 2, profilePicture: "bild_user28", name: "Klaus Baum", question: ["Blau oder Weiß ?", "Zimt oder Zucker ?", "Oben oder unten ?"]),
    11. Question(userID: 3, profilePicture: "bild_user29", name: "Travis Scott", question: ["Das oder Das ?", "Früchte oder Gemüse ?", "Welches T-shirt ?"]),
    12. Question(userID: 4, profilePicture: "bild_user30", name: "DJ Bobo", question: ["Ist das gut so ?", "Voll cool oder ?", "Welche Marke ist am besten ?"])
    13. ]
    Alles anzeigen


    Quellcode

    1. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    2. //Zählt die User im Array
    3. if section == 0 {
    4. return 1
    5. } else {
    6. for user in questions where user.userID == userSegueID {
    7. return user.question.count
    8. }
    9. }
    10. return 0
    11. }
    Alles anzeigen

    Quellcode

    1. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    2. let backItem = UIBarButtonItem()
    3. backItem.title = "Back"
    4. navigationItem.backBarButtonItem = backItem
    5. if segue.identifier == "votingSegue" {
    6. guard
    7. let index = profileTableView.indexPathForSelectedRow?.row,
    8. let destViewController = segue.destination as? VotingViewController
    9. else { return }
    10. destViewController.moveID = index
    11. for user in questions where user.userID == userSegueID {
    12. let questionPath = user.question[index]
    13. let picturePath = user.profilePicture
    14. let titlePath = user.name
    15. destViewController.profilePicture = UIImage(named: picturePath)!
    16. destViewController.questionLabelText = questionPath
    17. destViewController.titleName = titlePath
    18. destViewController.userSegueID = self.userSegueID
    19. print("\(index): '\(questionPath)'")
    20. }
    21. }
    22. }
    Alles anzeigen

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ThisIsBeat ()

  • Also die Variablenbezeichnung userSegueID finde ich ungünstig gewählt, handelt es sich doch einfach um die UserID, die Segue hat damit doch gar nichts zu tun.

    Ansonsten liest sich for user in questions where user.userID == userSegueID {...} für mich gruselig. Du willst doch nur aus dem Array das Objekt haben, dessen Property userID dem gewählten Wert entspricht. Muss man dafür durch das Array iterieren? Ich kann kein Swift, möchte mir aber nicht vorstellen, dass es dafür keinen besseren Weg gibt. Ich würde das eher über ein Predicate lösen (wobei ich nicht weiss, ob das intern besser ist). So etwas in der Art

    Quellcode

    1. NSPredicate *predicate = [NSPredicate predicateWithFormat:@"userID == %@", userSegueID];
    2. NSArray *filteredArray = [questions filteredArrayUsingPredicate:predicate];
    3. id firstFoundObject = nil;
    4. firstFoundObject = filteredArray.count > 0 ? filteredArray.firstObject : nil;
    Das würde ich ausserdem in eine Funktion auslagern, da Du die Identifikation des User-Objektes mehrmals brauchst.

    Mattes
    Diese Seite bleibt aus technischen Gründen unbedruckt.