将数据从plist加载到两个TableViews

我有一些麻烦,从我的属性列表中加载一些数据。 看看…这是我的directory.plistdirectory.plist

我想在Main.storyboard上显示所有这些,就在这里: Main.storyboard

但是, Position e Name将显示在第一个TableViewController上 ,并且键FunctionaryImageFacePhone必须出现在第二个TableViewController上

要做到这一点,我做了这个:

  1. 添加到AppDelegate下面:

     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { if let url = Bundle.main.url(forResource: "directory", withExtension: "plist"), let array = NSArray(contentsOf: url) as? [[String:Any]] { Shared.instance.employees = array.map{Employee(dictionary: $0)} } return true 
  2. 像这样创build一个Struct

     struct EmployeeDetails { let functionary: String let imageFace: String let phone: String init(dictionary: [String: Any]) { self.functionary = (dictionary["Functionary"] as? String) ?? "" self.imageFace = (dictionary["ImageFace"] as? String) ?? "" self.phone = (dictionary["Phone"] as? String) ?? "" } } struct Employee { let position: String let name: String let details: [EmployeeDetails] // [String:Any] init(dictionary: [String: Any]) { self.position = (dictionary["Position"] as? String) ?? "" self.name = (dictionary["Name"] as? String) ?? "" let t = (dictionary["Details"] as? [Any]) ?? [] self.details = t.map({EmployeeDetails(dictionary: $0 as! [String : Any])}) } } struct Shared { static var instance = Shared() var employees: [Employee] = [] } 
  3. 我的第一个TableViewController ,是这样的:

     class Page1: UITableViewController { override func viewDidLoad() { super.viewDidLoad() let anEmployee = Shared.instance.employees[1] print("Name:", anEmployee.name) print("Position:", anEmployee.position) anEmployee.details.forEach({ print("Functionary:", $0.functionary) print("ImageFace:", $0.imageFace) print("Phone:", $0.phone) }) } override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return Shared.instance.employees.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell1 cell.nameLabel.text = Shared.instance.employees[indexPath.row].name cell.positionLabel.text = Shared.instance.employees[indexPath.row].position return cell } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { if let destination = segue.destination as? Page2, let indexPath = tableView.indexPathForSelectedRow { destination.newPage = Shared.instance.employees[indexPath.row].details[indexPath.row] tableView .deselectRow(at: indexPath, animated: true) } } } 
  4. 我的第二个TableViewController ,在这里:

     var newPage: EmployeeDetails! //recently added class Page2: UITableViewController { var newPage: EmployeeDetails! override func viewDidLoad() { super.viewDidLoad() if let theEmployee = newPage { self.title = theEmployee.name } } override func numberOfSections(in tableView: UITableView) -> Int { return 1 } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if let theEmployee = newPage { return theEmployee.details.count } return 0 } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell2 if let theEmployee = newPage { cell.faceImage.image = theEmployee.details[indexPath.row].imageFace as? UIImage // did not work cell.functionary.text = theEmployee.details[indexPath.row].functionary cell.phoneLabel.text = theEmployee.details[indexPath.row].phone } return cell } } 

当我触摸第一个TableViewController的任何项目,我看到第二个TableViewController完全是空的! debugging区域显示它:

 2017-03-28 17:16:28.456 plist sample[7138:425253] Unknown class Page2 in Interface Builder file. 

根据你的plist结构:

 Shared.instance.employees[indexPath.row].details 

details是一个字典数组。 你正在把它当作一个词典。

编辑:最初的问题是正确的…多种方式来解决它(如你所见/完成)。 另一个选项,这可能会或可能不会有所帮助:

 struct EmployeeDetails { let functionary: String let imageFace: String let phone: String init(dictionary: [String: Any]) { self.functionary = (dictionary["Functionary"] as? String) ?? "" self.imageFace = (dictionary["ImageFace"] as? String) ?? "" self.phone = (dictionary["Phone"] as? String) ?? "" } } struct Employee { let position: String let name: String let details: [EmployeeDetails] // [String:Any] init(dictionary: [String: Any]) { self.position = (dictionary["Position"] as? String) ?? "" self.name = (dictionary["Name"] as? String) ?? "" let t = (dictionary["Details"] as? [Any]) ?? [] self.details = t.map({EmployeeDetails(dictionary: $0 as! [String : Any])}) } } struct Shared { static var instance = Shared() var employees: [Employee] = [] } 

你可以做你的原创:

  if let url = Bundle.main.url(forResource: "directory", withExtension: "plist"), let array = NSArray(contentsOf: url) as? [[String:Any]] { Shared.instance.employees = array.map{Employee(dictionary: $0)} } 

然后通过以下方式访问数据:

  let anEmployee = Shared.instance.employees[0] print("Name:", anEmployee.name) print("Position:", anEmployee.position) print("Detail 0 Functionary:", anEmployee.details[0].functionary) print("Detail 0 ImageFace:", anEmployee.details[0].imageFace) print("Detail 0 Phone:", anEmployee.details[0].phone) // or anEmployee.details.forEach({ print("Functionary:", $0.functionary) print("ImageFace:", $0.imageFace) print("Phone:", $0.phone) }) 

只是例如。

看到一个工作的例子https://github.com/DonMag/SWPListData