2016-12-31 1 views
0

ich mit dem folgenden bin zu kämpfen:Swift - für UITableViewController relativ komplexe Anordnung Lese

Ich versuche, in einem Array zu entwerfen und zu lesen, dass die Informationen für einen UITableViewController hält.

Die Tabellenansicht enthält mehrere Abschnitte, wobei jeder Abschnitt einige Zellen enthält und jede Zelle einen Namen und einen Ein/Aus-Schalter hat.

Mit Hilfe von stackoverlfow konnte ich zu dem Punkt unterhalb kommen, wo ich fast alles außer der Standardposition für den UISwitch habe.

import UIKit 

class SettingsTableViewController: UITableViewController { 

    var sections = ["Panels:": ["Radar", "ADIRs", "Transponder"], "Engine Type:": ["IAE", "CFM", "NEO"]] 

    struct Objects { 

     var sectionName: String! 
     var sectionObjects: [String]! 
    } 

    var objectArray = [Objects]() 

    let cellId = "cellId" 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     for (key, value) in sections { 
      print("\(key) \(value)") 
      objectArray.append(Objects(sectionName: key, sectionObjects: value)) 
     } 

     navigationItem.title = "Settings" 
     tableView.register(PanelCell.self, forCellReuseIdentifier: cellId) 
     tableView.allowsSelection = false 
     navigationItem.leftBarButtonItem = UIBarButtonItem(title: "< BACK", style: .plain, target: self, action: #selector(self.navigateBack)) 
    } 

    func navigateBack() { 
     self.dismiss(animated: true, completion: nil) 
    } 

    // MARK: - Table view data source 

    override func numberOfSections(in tableView: UITableView) -> Int { 
     return sections.count 
    } 

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return objectArray[section].sectionObjects.count 
    } 

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! PanelCell 
     cell.nameLabel.text = objectArray[indexPath.section].sectionObjects[indexPath.row] 
     cell.panelSwitch.isOn = true 
     cell.settingsTableViewController = self 
     return cell 
    } 

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
     return objectArray[section].sectionName 
    } 
} 

... Also, um die Ausgangsposition des UISwitch ich ein anderes Array wie folgt zu gestalten haben zu schließen versucht:

var sections:[(sectionTitle: String, [(itemTitle: String, defaultValue: Bool)])] = [ 
    ("Panels", [("Radar",false),("ADIRs",false),("Transponder",false)]), 
    ("Engine Type", [("IAE",false),("CFM",true),("NEO",false)]) 
] 

Ich habe die Objekte geändert struct wie folgt:

struct Object { 

    var sectionName: String! 
    var items: [(title: String, onOff: Bool)]! 
} 

Allerdings kann ich nicht herausfinden, wie all dies in ein Array von Objekten gelesen wird.

var objectArray = [Object]() 
var object = Object() 

for index in sections { 

    print("\(index)") 
    object.sectionName = index[0].sectionTitle 
} 

Die letzte Zeile oben gibt mir einen Fehler. Wenn ich versuche, es so zugreifen es funktioniert:

print("\(sections[0].sectionTitle)") 
print("\(sections[0].1[0].itemTitle)") 
print("\(sections[0].1[0].defaultValue)") 
print("\(sections[0].1[1].itemTitle)") 
print("\(sections[0].1[1].defaultValue)") 
print("\(sections[0].1[2].itemTitle)") 
print("\(sections[0].1[2].defaultValue)") 

So habe ich keine Ahnung, wie dieses Array in objectArray richtig zu lesen. Ich habe auch das Gefühl, dass meine ganze Herangehensweise an das Problem einfach falsch ist.

Danke für die Hilfe!

Antwort

1

ich ein wenig Code aktualisieren, damit es funktioniert:

typealias CellObject = (title: String, onOff: Bool) 

class SettingsTableViewController: UITableViewController { 

    var sections: [String: [CellObject]] = [ 
     "Panels:": 
      [("Radar", true), 
      ("ADIRs", false), 
      ("Transponder", false) 
     ], 
     "Engine Type:": [ 
      ("IAE", true), 
      ("CFM", false), 
      ("NEO", false) 
     ] 
    ] 

    struct Objects { 

     var sectionName: String 
     var sectionObjects: [CellObject] 
    } 

    var objectArray = [Objects]() 

    let cellId = "cellId" 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     for (key, value) in sections { 
      print("\(key) \(value.count)") 
      objectArray.append(Objects(sectionName: key, sectionObjects: value)) 
     } 

     navigationItem.title = "Settings" 
     tableView.register(PanelCell.self, forCellReuseIdentifier: cellId) 
     tableView.allowsSelection = false 
     navigationItem.leftBarButtonItem = UIBarButtonItem(title: "< BACK", style: .plain, target: self, action: #selector(self.navigateBack)) 
    } 

    func navigateBack() { 
     self.dismiss(animated: true, completion: nil) 
    } 

    // MARK: - Table view data source 

    override func numberOfSections(in tableView: UITableView) -> Int { 
     return objectArray.count // don't use sections object anymore 
    } 

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return objectArray[section].sectionObjects.count 
    } 

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! PanelCell 
     let item = objectArray[indexPath.section].sectionObjects[indexPath.row] 
     cell.nameLabel.text = item.title 
     cell.panelSwitch.isOn = item.onOff 
     // cell.settingsTableViewController = self // you should not pass controller to the cell 
     return cell 
    } 

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
     return objectArray[section].sectionName 
    } 
} 

EDITED

Für das Wörterbuch Bestellung unsicher Problem zu vermeiden, kann die Datenstruktur (als JSON-Format) sein:

:

[ 
    { 
    "title": "Panels", 
    "items": [ 
     { 
     "name": "Radar", 
     "selected": true 
     }, 
     { 
     "name": "ADIRs", 
     "selected": false 
     }, 
     { 
     "name": "Transponder", 
     "selected": false 
     } 
    ] 
    }, 
    { 
    "title": "Engine Type", 
    "items": [ 
     { 
     "name": "IAE", 
     "selected": true 
     }, 
     { 
     "name": "CFM", 
     "selected": false 
     }, 
     { 
     "name": "NEO", 
     "selected": false 
     } 
    ] 
    } 
] 

Die Datenklasse kann definiert werden als

class Data { 
    var title: String? 
    var items: [Detail]? 
} 

class Detail { 
    var name: String? 
    var selected: Bool? 
} 

Dann ist Ihr Array der Typ var objectArray = [Data](). Konvertieren Sie die JSON-Zeichenfolge in [[String: Any]] und setzen Sie sie auf objectArray (Google oder durchsuchen Sie diese Website nach dem Konvertieren von JSON-Zeichenfolge in Array).

Wenn die Daten das Wörterbuch zurückgeben müssen, müssen Sie mit Ihrem Kunden oder Teamkollegen besprechen, wie Sie die Wörterbuchschlüssel am besten bestellen, um sicherzustellen, dass die Daten wie erwartet vorliegen.

+0

Zur Erinnerung: Da Sie Dictionary verwenden, um in ein Array zu konvertieren, kann die Reihenfolge in objectArray unsicher sein. – bubuxu

+0

bubuxu! Das funktioniert großartig! DANKE!!! Weit über meiner Gehaltsstufe. Um die Bestellung zu sichern, welchen anderen Sammlertyp sollte ich anstelle von Wörterbüchern verwenden? – user1269290

+0

@ user1269290 In der aktualisierten Antwort finden Sie Erläuterungen zum Vermeiden des unsicheren Wörterbuchs. – bubuxu

Verwandte Themen