我正在尝试从 plist 文件加载数据并按字母顺序过滤并用它填充表视图。
let url = Bundle.main.url(forResource: "Names", withExtension: "plist")!
let data = try! Data(contentsOf: url)
nameArray = try! PropertyListSerialization.propertyList(from: data, options: [], format: nil) as! [String]
alphabetsSection = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
for letter in alphabetsSection {
let predicate = NSPredicate(format: "SELF beginswith[c] %@", letter)
arrayForSection = nameArray.filter { predicate.evaluate(with: $0) }
print(arrayForSection.count)
}
设置表视图:
func numberOfSections(in tableView: UITableView) -> Int {
return alphabetsSection.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return String(describing: alphabetsSection[section])
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayForSection[section].count
}
由于numberOfRowsInSection
中的Thread 1: Fatal error: Index out of range
,应用程序崩溃。我检查并意识到arrayForSection.count
只适用于for
语句,为什么?
问题是您将过滤后的数组直接分配给arrayForSection
。 因此,新部分的过滤值将被覆盖在上一节的值上。
而
您应该像为每个部分保留一个过滤数组一样这样做,以防万一某个字母没有过滤值,那么特定部分(部分引用字母表(将存在空数组。
要解决此问题,请执行以下操作:
将过滤结果添加到数组arrayForSection
:
var arrayForSection: [[String]] = []
for letter in alphabetsSection {
let predicate = NSPredicate(format: "SELF beginswith[c] %@", letter)
let filteredResult = nameArray.filter {
predicate.evaluate(with: $0)
}
arrayForSection.append(filteredResult)
}
为了测试它,我取了一个数组:
let nameArray = ["Apple","Cherry","Chips","Mango","Magento","Juice","Strawberry"]
结果是:
[["Apple"], [], ["Cherry", "Chips"], [], [], [], [], [], [], ["Juice"], [], [], ["Mango", "Magento"], [], [], [], [], [], ["Strawberry"], [], [], [], [], [], [], []]
因此,对于每个部分,您将获得一个数组,要么包含数据,要么为空。所以在arrayForSection[section].count
,你不会得到Thread 1: Fatal error: Index out of range
.
希望这会有所帮助。
Dictionary
有一种方便的方法来对项目数组进行分组
let dataSource = Dictionary(grouping: nameArray, by: { String($0.prefix(1))})
let alphabetsSection = dataSource.keys.sorted()
对应的表视图数据源和委托方法是
func numberOfSections(in tableView: UITableView) -> Int {
return alphabetsSection.count
}
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
return alphabetsSection[section]
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let firstLetter = alphabetsSection[section]
return dataSource[firstLetter]!.count
}