将数据从一个plist加载到两个TableViews [英] Load data from a plist to two TableViews

查看:79
本文介绍了将数据从一个plist加载到两个TableViews的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从属性列表中加载某些数据时遇到麻烦.看一看… 这是我的directory.plist:

I am having some trouble to load some data from my property list. Take a look… This is my directory.plist:

我想在Main.storyboard上显示所有这些内容:

I wanna show all of this, right here on Main.storyboard:

但是键Position e Name将出现在第一个 TableViewController 上,而键FunctionaryImageFacePhone则必须出现在第二个 TableViewController上.

But the keys Position e Name will appear on the first TableViewController and the keys Functionary, ImageFace and Phone have to appear on the second 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

  • 像这样创建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] = []
    }
    

  • 我的第一个TableViewController 就像这样:

  • My First TableViewController, is like this:

    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)
            }
        }
    }
    

  • 我的第二个TableViewController ,在这里:

  • My Second TableViewController, here:

    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完全是空的!调试区域显示它:

    When I touch in any item of the first TableViewController, I see the second TableViewController totally empty! And the debug area shows it:

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

    推荐答案

    根据您的plist结构:

    According to your plist structure:

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

    details是字典数组.您将其视为字典.

    details is an Array of Dictionaries. You are treating it as a Dictionary.

    最初的问题是正确的……有多种解决方法(如您所见/完成).另一个选择可能会或可能不会有帮助:

    the initial issue was correct... multiple ways to solve it (as you have seen / done). Another option, which may or may not be helpful:

    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] = []
    }
    

    然后您可以制作原始照片:

    you can then do your original:

        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)}
    
        }
    

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

    and then access the data via:

        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 .

    See https://github.com/DonMag/SWPListData for a working example.

    这篇关于将数据从一个plist加载到两个TableViews的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆