将列表排序为tableview索引的部分

时间:2014-11-09 16:44:25

标签: ios arrays sorting dictionary swift

我正在寻找获取列表的最佳方法,并将其分类为用于侧面的tableView索引的部分。在我的例子中,按Make的第一个字母排序Car对象。我以为我想要一个Car对象的字典,最多有26个键,但还没有工作。如果我有一种更好的方式可以忽略,我很乐意听到它。

非常感谢任何帮助。

在游乐场样品中粘贴。

// Playground - noun: a place where people can play

import UIKit

var str = "Hello, playground"

let indexList = ["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"]

func gimmeOne(things: [String]) -> String {
    let randomNumber = Int(arc4random()) % things.count
    let choice = things[randomNumber]
    return choice
}

func gimmeCarMake() -> String {
    let makes = ["Ford","Audi","Hennessey","Acura","Infiniti","BMW","Lexus","Jeep","Subaru","Nissan","Aston Martin","Mercedes-Benz","Porsche","Toyota","Volkswagen","Scion","Mitsubishi","Mini","Lotus","Lamborghini","Jaguar","Hyundai","Citroën","Cadillac","Bugatti","Bentley","Alfa Romeo","Dodge"]
    return gimmeOne(makes)
}

class Car:NSObject {
    var make: String

    override init() {
        self.make = gimmeCarMake()
    }
}

//create list of cars
var carList = [Car]()
for _ in 0..<10 {
    carList.append(Car())
}
carList


//sort list
carList.sort { $0.make < $1.make }
carList


func firstLetter(text: String) -> String {
    let position = 0
    let index = advance(text.startIndex, position)
    let character = "\(text[index])"
    return character
}


//goal - to be used in tableView index section
//["A"] = ["Acura","Aston Martin","Audi"]
//["B"] = ["BMW","Bentley"]
//["C"] = ["Cadillac","Citroën"]
//["D"] = ["Dodge"]

修改 让我们看看我是否可以失去其余的声望点。

我在代码中找到了最终答案,并且它足够通用,所以任何人都可以通过一些快速更改来使用它。如果您需要遵循的步骤,请查看this page

希望它有所帮助。

//
//  ViewController.swift
//  tmpSortTable
//
// Solution from:
// http://www.pumpmybicep.com/2014/07/04/uitableview-sectioning-and-indexing/
//

import UIKit

class MyObject:NSObject {
    var thingA: String
    var thingB: String
    var section: Int?  //make room in your object for this

    class func gimmeOne(things: [String]) -> String {
        let randomNumber = Int(arc4random()) % things.count
        let choice = things[randomNumber]
        return choice
    }

    class func gimmeCarMake() -> String {
        let makes = ["Ford","Audi","Hennessey","Acura","Infiniti","BMW","Lexus","Jeep","Subaru","Nissan","Aston Martin","Mercedes-Benz","Porsche","Toyota","Volkswagen","Scion","Mitsubishi","Mini","Lotus","Lamborghini","Jaguar","Hyundai","Citroën","Cadillac","Bugatti","Bentley","Alfa Romeo","Dodge","Tesla"]
        return gimmeOne(makes)
    }

    class func gimmeCarModel() -> String {
        let model = ["F150","Mustang","LFA","S55","Raptor","Odyssey","NSX","4C","F40","F50","F70","LaFerrari","Camry","Silverado","Viper","Routan","Quattro","M100","P85 D","Stealth","Pinto","Accord"]
        return gimmeOne(model)
    }

    override init() {
        self.thingA = MyObject.gimmeCarMake()
        self.thingB = MyObject.gimmeCarModel()
    }

    override var description: String {
        return "\n\(thingA) \(thingB) in section \(section)"
    }
}



class ViewController: UITableViewController {

    //setup
    var data = [MyObject]()  //main list of data to be used

    override func viewDidLoad() {
        super.viewDidLoad()
        createData()
    }

    //create data or fill data any way you want
    func createData() {
        for _ in 0..<50 {
            data.append(MyObject())
        }
    }

    //now the important section stuff
    class Section {
        var items: [MyObject] = []

        func addItem(item: MyObject) {
            self.items.append(item)
        }

    }

    // `UIKit` convenience class for sectioning a table
    let collation = UILocalizedIndexedCollation.currentCollation() as UILocalizedIndexedCollation
    var sections: [Section] {
        if self._sections != nil {
            return self._sections!
        }

        //identify item to section
        var items: [MyObject] = data.map { dataItem in
            dataItem.section = self.collation.sectionForObject(dataItem, collationStringSelector: "thingA")
            return dataItem
        }

        //create empty sections
        var sections = [Section]()
        for _ in 0..<self.collation.sectionIndexTitles.count {
            sections.append(Section())
        }

        //put each item into a section
        for item in items {
            sections[item.section!].addItem(item)
        }

        //sort each section
        for section in sections {
            section.items = self.collation.sortedArrayFromArray(section.items, collationStringSelector: "thingA") as [MyObject]
        }

        self._sections = sections
        return self._sections!
    }
    var _sections: [Section]?





    //TableView data source
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return self.sections.count
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.sections[section].items.count
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let item = self.sections[indexPath.section].items[indexPath.row]
        let cell = tableView.dequeueReusableCellWithIdentifier("UITableViewCell", forIndexPath: indexPath) as UITableViewCell
        cell.textLabel.text = "\(item.thingA) \(item.thingB)"
        return cell
    }

    /* section headers appear above each `UITableView` section */
    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String {
        // do not display empty `Section`s
        if !self.sections[section].items.isEmpty {
            return self.collation.sectionTitles[section] as String
        }
        return ""
    }

    /* section index titles displayed to the right of the `UITableView` */
    override func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject] {
        return self.collation.sectionIndexTitles
    }

    override func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
        return self.collation.sectionForSectionIndexTitleAtIndex(index)
    }

}

2 个答案:

答案 0 :(得分:3)

在Swift中查看本教程Indexed Table View in Swift。您将要使用UILocalizedIndexedCollat​​ion便利类来创建索引,而不是手动或以编程方式执行。它使用“项目本地化”列表中定义的区域设置。这样您就不必自己创建列表,或者编写代码来执行此操作,并且在添加/删除更多条目时需要更少的维护。这也可以利用您最终在应用程序中进行的任何本地化。

您还可以查看UILocalized​Indexed​Collation on NSHipster以了解有关使用课程的详细信息。

答案 1 :(得分:1)

你可以使用下面的代码并执行buildIndex(words)来得到这样的东西:

[(A,[Acura,Auston Martin,Audi]),  (B,[宝马,宾利]),  (C,[Cadilac,Citroen]), .... ]

import Foundation

let makes = ["Ford","Audi","Hennessey","Acura","Infiniti","BMW","Lexus","Jeep","Subaru","Nissan","Aston Martin","Mercedes-Benz","Porsche","Toyota","Volkswagen","Scion","Mitsubishi","Mini","Lotus","Lamborghini","Jaguar","Hyundai","Citroën","Cadillac","Bugatti","Bentley","Alfa Romeo","Dodge"]

let words = makes.sorted({$0 < $1})

typealias Entry = (Character, [String])

func distinct<T: Equatable>(source: [T]) -> [T] {
  var unique = [T]()
  for item in source {
    if !contains(unique, item) {
      unique.append(item)
    }
  }
  return unique
}

func buildIndex(words: [String]) -> [Entry] {
  let letters = words.map {
    (word) -> Character in
    Character(word.substringToIndex(advance(word.startIndex, 1)
      ).uppercaseString)
  }
  let distinctLetters = distinct(letters)

  return distinctLetters.map {
    (letter) -> Entry in
    return (letter, words.filter {
      (word) -> Bool in
     Character(word.substringToIndex(advance(word.startIndex, 1)
       ).uppercaseString) == letter
    })
  }
}