如何使用可变数据源在表视图中按字母顺序排列节标题 [英] How to make alphabetically section headers in table view with a mutable data source

查看:97
本文介绍了如何使用可变数据源在表视图中按字母顺序排列节标题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将视图控制器的字符串存储在字符串数组中.我在表视图中将此字符串数组作为数据源导入.这一切都顺利进行.但是现在我想对表视图进行排序并添加节标题.节标题应该来自字母,意义节的行应该是数组中所有字符串,从节标题的字母开始.

I store strings of a view controller in a string array. I import this string array as a Data Source in my table view. This all works smoothly. But now I would like to sort the table view and add section headers. The section header should be from the alphabet, the rows of the meaning sections should be all strings from the array, starting with the letter of the section header.

我知道如何使用静态数组来实现这一目标.但是,如何确保仅显示这些部分,这些部分也具有行(数组中的字符串)?以及如何保存带有字母的新字符串时,它会生成一个新部分,而该部分中尚不存在该字母?

I know how I can achieve this with static arrays. But how can I make it that only the sections are shown, which also have rows(strings in the array)? And how can I make it so that it generates a new section when saving a new string with a letter, which does not yet exist in the sections?

我希望我已经足够准确地解释了.我尝试了很长时间来解决这个问题.如果有人可以帮助我,那就太好了.

I hope I have explained it accurately enough. I tried for a long time to solve this problem. It would be great if someone could help me.

以下是一些代码段:

class OverViewController: UIViewController {

@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var addButton: UIBarButtonItem!
@IBOutlet weak var editButton: UINavigationItem!


var kontaktListe = Telefonbuch.loadArray()
var sections = [[String]]()
var collation = UILocalizedIndexedCollation.currentCollation()


override func viewDidLoad()
{
    super.viewDidLoad()
    tableView.dataSource = self
    configureSectionData()
    tableView.reloadData()

}


func configureSectionData()
{
    let names = kontaktListe.map{$0.name}

    let selector: Selector = "description"


    sections = Array(count:collation.sectionTitles.count, repeatedValue: [])

    let sortedObjects = collation.sortedArrayFromArray(names, collationStringSelector: selector)

    for object in sortedObjects {
        let sectionNumber = collation.sectionForObject(object, collationStringSelector: selector)
        sections[sectionNumber].append(object as! String)
    }
}

我加载对象var kontaktListe = Telefonbuch.loadArray()并获得名称属性let names = kontaktListe.map{$0.name}.在这里,我想对字符串进行排序和添加.

I load the object var kontaktListe = Telefonbuch.loadArray() and get the name property let names = kontaktListe.map{$0.name}. And there I would like to get the strings to sort and add from.

推荐答案

我会更改将联系人存储到以首字母作为键的字典的方式,并将与该首字母对应的名称放入子数组: /p>

I would change the way you store your contacts to a dictonary with the initial letters as keys and put the names that correspond to that initial letter into a subarray:

contacts = ["A": ["Anton", "Anna"], "C": ["Caesar"]]

我简化了此处的联系方式(以字符串形式),但是您明白了.

I simplified the way of the contacts here (in form of strings), but you get the concept.

我也将字母的节号保存在这样的单独数组中:

I would also save the section number of the letter in a seperate array like this:

letters = ["A", "C"]

保持对数组进行排序和组织,因此请在每次插入/删除/更新后进行检查.这不是表视图实现的一部分.我将Viewcontroller设为电话簿的委托,因此您可以从电话簿中触发类似更新的方法来更新表格.

Keep the array sorted and organized, so check after each insertion/deletion/update. This is not part of the table view implementation. I would make the Viewcontroller a delegate of the phonebook, so you can fire an update-like method from the phonebook to update the table.

如何获取数据源的数据:

节数:

letters.count

索引i处的节标题为

letters[i]

第i部分的单元格数是

contacts[letters[i]].count

第i节中特定单元格c的内容为:

and the content for a specific cell c in section i is:

contacts[letters[i]][c]

如果仍然不清楚,请随时提出其他问题.

Feel free to ask further questions if anything is still not clear.

更新-如何生成数组:

我不需要对数据进行排序,如果您传递已经排序的数据,则可以删除下面的排序行...

I don't require the data to be sorted, if you pass it already sorted, you can delete the sorting lines below ...

let data = ["Anton", "Anna", "John", "Caesar"] // Example data, use your phonebook data here.

// Build letters array:

var letters: [Character]

letters = data.map { (name) -> Character in
    return name[name.startIndex]
}

letters = letters.sort()

letters = letters.reduce([], combine: { (list, name) -> [Character] in
    if !list.contains(name) {
        return list + [name]
    }
    return list
})


// Build contacts array:

var contacts = [Character: [String]]()

for entry in data {

    if contacts[entry[entry.startIndex]] == nil {
        contacts[entry[entry.startIndex]] = [String]()
    }

    contacts[entry[entry.startIndex]]!.append(entry)

}

for (letter, list) in contacts {
    list.sort()
}

对于 Swift 3 :

let data = ["Anton", "Anna", "John", "Caesar"] // Example data, use your phonebook data here.

// Build letters array:

var letters: [Character]

letters = data.map { (name) -> Character in
    return name[name.startIndex]
}

letters = letters.sorted()

letters = letters.reduce([], { (list, name) -> [Character] in
    if !list.contains(name) {
        return list + [name]
    }
    return list
})


// Build contacts array:

var contacts = [Character: [String]]()

for entry in data {

    if contacts[entry[entry.startIndex]] == nil {
        contacts[entry[entry.startIndex]] = [String]()
    }

    contacts[entry[entry.startIndex]]!.append(entry)

}

for (letter, list) in contacts {
    contacts[letter] = list.sorted()
}

我在操场上运行了代码,并得到了以下输出

I ran the code in playground and got the following outputs for

字母:

["A", "C", "J"]

联系人:

["J": ["John"], "C": ["Caesar"], "A": ["Anton", "Anna"]]

这篇关于如何使用可变数据源在表视图中按字母顺序排列节标题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆