将数据从 plist 加载到两个 TableView
Load data from a plist to two TableViews
我在从 属性 列表中加载一些数据时遇到了一些问题。看一看…
这是我的 directory.plist
:
我想展示所有这些,就在 Main.storyboard
上:
但是键Position
e Name
会出现在第一个TableViewController和键Functionary
,ImageFace
和Phone
必须出现在第二个 TableViewController.
为此,我做了这个:
向 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: [=10=])}
}
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: [=11=] as! [String : Any])})
}
}
struct Shared {
static var instance = Shared()
var employees: [Employee] = []
}
我的第一个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:", [=12=].functionary)
print("ImageFace:", [=12=].imageFace)
print("Phone:", [=12=].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,这里:
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: [=11=] 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: [=12=])}
}
然后通过以下方式访问数据:
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:", [=13=].functionary)
print("ImageFace:", [=13=].imageFace)
print("Phone:", [=13=].phone)
})
举个例子。
有关工作示例,请参阅 https://github.com/DonMag/SWPListData。
我在从 属性 列表中加载一些数据时遇到了一些问题。看一看…
这是我的 directory.plist
:
我想展示所有这些,就在 Main.storyboard
上:
但是键Position
e Name
会出现在第一个TableViewController和键Functionary
,ImageFace
和Phone
必须出现在第二个 TableViewController.
为此,我做了这个:
向 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: [=10=])} } 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: [=11=] as! [String : Any])}) } } struct Shared { static var instance = Shared() var employees: [Employee] = [] }
我的第一个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:", [=12=].functionary) print("ImageFace:", [=12=].imageFace) print("Phone:", [=12=].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,这里:
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: [=11=] 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: [=12=])}
}
然后通过以下方式访问数据:
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:", [=13=].functionary)
print("ImageFace:", [=13=].imageFace)
print("Phone:", [=13=].phone)
})
举个例子。
有关工作示例,请参阅 https://github.com/DonMag/SWPListData。