Как заполнить разделы индексированного UITableView другим массивом для sectionIndexTitles - PullRequest
0 голосов
/ 22 мая 2019

Я использую массив имен людей для загрузки таблицы. Я хочу отделить разделы в зависимости от государства проживания каждого человека, оставляя разделыIndexTitles ограниченными первой буквой названия штата. Мой sectionIndexTitles будет т.е. ["A", "C", "D", "F", "G", "H", "I", "K", "L", "M", "N", "O", "P", "R", "S", "T", "U", "V", "W"], в то время как разделы таблицы будут разделены на все 50 состояний.

По сути, буква А (индекс 0) будет принадлежать Аляске, Алабаме, Арканзасу и Аризоне. B нет, поэтому следующая буква C (индекс 2) должна прокручиваться до Калифорнии, число разделов которой равно 4.

Проблема, с которой я сталкиваюсь, заключается в том, что разделы, очевидно, не проиндексированы должным образом, поэтому при нажатии на любой проиндексированный заголовок, кроме буквы A, табличное представление не прокручивается до нужной буквы.

1 Ответ

2 голосов
/ 22 мая 2019

Сгруппируйте массив people по имени штата и создайте массив кортежей из словаря. Затем используйте этот массив в методах источника данных tableview

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    struct Person {
        var name: String
        var state: String
    }
    var allPeople = [Person]()
    var groupedPeople = [(state:String, people:[Person])]()
    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        allPeople = [Person(name: "a", state: "Alaska"), Person(name: "x", state: "Florida"),
                     Person(name: "c", state: "California")]
        groupedPeople = Dictionary(grouping: allPeople, by: { $0.state }).sorted(by: { $0.key < $1.key })
            .map({ (state:$0.key, people:$0.value)
            })
    }
    func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        return Array(Set(groupedPeople.map({ String($0.state.first!) })))
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return groupedPeople.count
    }
    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return groupedPeople[section].state
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return groupedPeople[section].people.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell(style: .subtitle, reuseIdentifier: "cell")
        cell.textLabel?.text = groupedPeople[indexPath.section].people[indexPath.row].name
        cell.detailTextLabel?.text = groupedPeople[indexPath.section].people[indexPath.row].state
        return cell
    }
}

Обновление

Если у вас больше секций, чем sectionIndexTitles, вы должны реализовать метод sectionForSectionIndexTitle и вернуть соответствующий индекс секции.

func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
    if let index = groupedPeople.firstIndex(where: { $0.state.hasPrefix(title) }) {
        return index
    }
    return 0
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...