ios - 将数据从 plist 加载到两个 TableView

标签 ios swift xcode uitableview plist

我在从我的属性列表中加载一些数据时遇到了一些问题。看一看… 这是我的 directory.plist: directory.plist

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

但是键 Position e Name 将出现在第一个 TableViewController 和键 Functionary, ImageFacePhone 必须出现在第二个 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. 像这样创建了一个结构:

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

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一个工作示例。

关于ios - 将数据从 plist 加载到两个 TableView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43073516/

相关文章:

ios - Cordova iOS指纹认证:将用户凭据发送到服务器

ios - 如何为谷歌地图 IOS 设置可见区域/缩放级别以显示添加到 map View 的所有标记

ios - 重写后总是调用 super?

ios - 如何按整数值对NSDictionary排序?

ios - 在文档中写入视频时出错

ios - 如何创建一个打开/关闭 collectionView 部分

xcode - Instruments 中的  "dirty"内存是什么?

xcode - 如何让 Xcode 始终在变量监视列表中显示一个寄存器?

ios - 将 3D SceneKit 节点位置映射到 2D 坐标 - projectPoint 不起作用

ios - iAd 加载时 Adwhirl 崩溃