如何使用可变数据源在表视图中按字母顺序创建节标题

时间:2016-04-09 19:20:22

标签: swift header tableview sections

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

我知道如何使用静态数组实现这一目标。但是我怎么能只显示那些也有行(数组中的字符串)的部分呢?我怎样才能使它在保存带字母的新字符串时生成一个新的部分?这些部分中尚不存在?

我希望我已经足够准确地解释了它。我试了很久才解决这个问题。如果有人可以帮助我会很棒。

以下是一些代码段:

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}。在那里,我想得到字符串进行排序和添加。

2 个答案:

答案 0 :(得分:4)

Swift 3 。谢谢@Stefan!这是我的Set

版本
var tableViewSource: [Character : [String]]!
var tableViewHeaders: [Character]!

let data = ["Anton", "Anna", "John", "Caesar"]

func createTableData(wordList: [String]) -> (firstSymbols: [Character], source: [Character : [String]]) {

    // Build Character Set
    var firstSymbols = Set<Character>()

    func getFirstSymbol(word: String) -> Character {
        return word[word.startIndex]
    }

    wordList.forEach {_ = firstSymbols.insert(getFirstSymbol(word: $0)) }

    // Build tableSourse array
    var tableViewSourse = [Character : [String]]()

    for symbol in firstSymbols {

        var words = [String]()

        for word in wordList {
            if symbol == getFirstSymbol(word: word) {
                words.append(word)
            }
        }

        tableViewSourse[symbol] = words.sorted(by: {$0 < $1})
    }

    let sortedSymbols = firstSymbols.sorted(by: {$0 < $1})

    return (sortedSymbols, tableViewSourse)
}

func getTableData(words: [String]) {
    tableViewSource = createTableData(wordList: words).source
    tableViewHeaders = createTableData(wordList: words).firstSymbols
}

getTableData(words: data)

print(tableViewSource)  // ["J": ["John"], "C": ["Caesar"], "A": ["Anna", "Anton"]]
print(tableViewHeaders) // ["A", "C", "J"]

答案 1 :(得分:2)

我是在一个循环中完成的,而不是很少( Swift 4 ):

struct ContactData {
    let longName: String
    let phones: [String]
    let thumbnailImageData: Data?
}
var contacts = [ContactData]()
var tableViewSource = [Character : [ContactData]]()
var headerTitles = [Character]()

func createContactsData(completionHandler: @escaping () -> Swift.Void) {
    contacts = extractContacts() // convert CNContact to custom ContactData
    tableViewSource.removeAll()
    var prevChar: Character?
    var currentBatch: [ContactData]!
    contacts.forEach { contact in
        guard let firstChar = contact.longName.first else {
            return
        }
        if prevChar != firstChar {
            if prevChar != nil {
                tableViewSource[prevChar!] = currentBatch
            }
            prevChar = firstChar
            currentBatch = [ContactData]()
        }
        currentBatch.append(contact)
    }

    let allKeys = Array(tableViewSource.keys)
    let sortedSymbols = allKeys.sorted(by: {$0 < $1})
    headerTitles = sortedSymbols
    completionHandler()
}