Plist 文件中的行数问题



我正在尝试从 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
}