【问题标题】:Alphabetical sections in table table view in swiftswift中表格视图中的字母部分
【发布时间】:2015-01-22 11:30:44
【问题描述】:

我有一个按字母顺序排序的名称列表,现在我想在表格视图中显示这些名称。我正在努力为每个字母分组这些名称。

我的代码如下所示:

let sections:Array<AnyObject> = ["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"]
var usernames = [String]()

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
    
    let cellID = "cell"
    
    let cell: UITableViewCell = self.tv.dequeueReusableCellWithIdentifier(cellID) as UITableViewCell
    
    cell.textLabel?.text = usernames[indexPath.row]
    
return cell
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
    
    return usernames.count
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int{
    
    return 26
}


func sectionIndexTitlesForTableView(tableView: UITableView) -> [AnyObject]!{
    
    return self.sections
}

func tableView(tableView: UITableView,
    sectionForSectionIndexTitle title: String,
    atIndex index: Int) -> Int{
        
        return index
}

func tableView(tableView: UITableView,
    titleForHeaderInSection section: Int) -> String?{
        
        return self.sections[section] as? String
}

这一切都很好,除了分组使我的表格视图最终变成这样:

所以我知道你应该可以在数组中使用过滤函数,但我不明白如何实现它。

任何关于如何进行的建议将不胜感激。

【问题讨论】:

  • cell.textLabel?.text = usernames[indexPath.row] 是您的问题根源。您不断用完全相同的数据填充每个部分。
  • 是的,我只需要正确过滤用户名数组:)
  • 虽然下面有一些尝试-我发现这个objective-c更可靠github.com/chrisladd/CGLAlphabetizer/blob/master/Example/…

标签: ios uitableview swift nsarray


【解决方案1】:

在 Swift 4 中,Dictionary(grouping:by:) 被引入以通过任意谓词将序列分组到字典中。

此示例将分组字典映射到自定义结构 Section

struct Section {
    let letter : String
    let names : [String]
}

...

let usernames = ["John", "Nancy", "James", "Jenna", "Sue", "Eric", "Sam"]

var sections = [Section]()

override func viewDidLoad() {
    super.viewDidLoad()

    // group the array to ["N": ["Nancy"], "S": ["Sue", "Sam"], "J": ["John", "James", "Jenna"], "E": ["Eric"]]
    let groupedDictionary = Dictionary(grouping: usernames, by: {String($0.prefix(1))})
    // get the keys and sort them
    let keys = groupedDictionary.keys.sorted()
    // map the sorted keys to a struct
    sections = keys.map{ Section(letter: $0, names: groupedDictionary[$0]!.sorted()) }
    self.tableView.reloadData()
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cellID = "cell"
    let cell = tableView.dequeueReusableCell(withIdentifier: cellID, for: indexPath)
    let section = sections[indexPath.section]
    let username = section.names[indexPath.row]
    cell.textLabel?.text = username
    return cell
}

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

func numberOfSections(in tableView: UITableView) -> Int {
    return sections.count
}

func sectionIndexTitles(for tableView: UITableView) -> [String]? {
    return sections.map{$0.letter}
}

func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return sections[section].letter
}

【讨论】:

  • 你是生命的救星。非常感谢
  • @vadian 太棒了?
【解决方案2】:

这就是我最近以编程方式在 Swift 中的 tableView 中实现排序列表的方式,

import UIKit

class BreedController: UITableViewController{

    var breeds = ["A": ["Affenpoo", "Affenpug", "Affenshire", "Affenwich", "Afghan Collie", "Afghan Hound"], "B": ["Bagle Hound", "Boxer"]]

    struct Objects {
        var sectionName : String!
        var sectionObjects : [String]!
    }

    var objectArray = [Objects]()

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.delegate = self
        tableView.dataSource = self
        tableView.registerClass(UITableViewCell.classForCoder(), forCellReuseIdentifier: "Cell")
        // SORTING [SINCE A DICTIONARY IS AN UNSORTED LIST]
        var sortedBreeds = sorted(breeds) { $0.0 < $1.0 }
        for (key, value) in sortedBreeds {
            println("\(key) -> \(value)")
            objectArray.append(Objects(sectionName: key, sectionObjects: value))
        }
    }

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return objectArray.count
    }

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

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
        // SETTING UP YOUR CELL
        cell.textLabel?.text = objectArray[indexPath.section].sectionObjects[indexPath.row]
        return cell
    }

    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return objectArray[section].sectionName
    }


}

【讨论】:

    【解决方案3】:

    下载 CountryList Json 文件并放入您的项目中

    https://gist.github.com/keeguon/2310008

       var json = NSArray()
       var arr_name = NSArray()
       var arrIndexSection : NSArray = ["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"]
    
    
    override func viewDidLoad() {
    
       let path = Bundle.main.path(forResource: "countries", ofType: "json")
        let data = NSData(contentsOfFile: path! )
        json = (try! JSONSerialization.jsonObject(with: data as! Data, options: JSONSerialization.ReadingOptions.mutableContainers)) as! NSArray
        arr_name = json.value(forKey: "name") as! NSArray;
    
        tableview.reloadData()
        super.viewDidLoad()
    }
    // Side List in tableview
    public func numberOfSections(in tableView: UITableView) -> Int {
        return 26
    }
    public func sectionIndexTitles(for tableView: UITableView) -> [String]? {
        return self.arrIndexSection as? [String] //Side Section title
    }
    public func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int
    {
        return index
    }
    
    
    public func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return arrIndexSection.object(at: section) as? String
    }
    
    
    // number of rows in table view
    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
    {
        let predicate = NSPredicate(format: "SELF beginswith[c] %@", arrIndexSection.object(at: section) as! CVarArg)
        let arrContacts = (arr_name as NSArray).filtered(using: predicate)
        return arrContacts.count;
    
    }
    
    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell : TableViewCell=self.tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TableViewCell
        let predicate = NSPredicate(format: "SELF beginswith[c] %@", arrIndexSection.object(at: indexPath.section) as! CVarArg)
        let arrContacts = (arr_name as NSArray).filtered(using: predicate) as NSArray
        cell.textLabel?.text = arrContacts.object(at: indexPath.row) as? String
        return cell
    }
    

    【讨论】:

      【解决方案4】:

      您可以将带有名称的数组放入带有字母键的字典中。

      例如

      var names = ["a": ["and", "array"], "b": ["bit", "boring"]]; // dictionary with arrays setted for letter keys
      

      那么你需要用下一种方式访问​​字典中的值

      func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
          return names[usernames[section]].count; // maybe here is needed to convert result of names[...] to NSArray before you can access count property
      }
      
      func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell{
      
          let cellID = "cell"
      
          let cell: UITableViewCell = self.tv.dequeueReusableCellWithIdentifier(cellID) as UITableViewCell
      
          cell.textLabel?.text = names[usernames[indexPath.section]][indexPath.row]; // here you access elements in arrray which is stored in names dictionary for usernames[indexPath.section] key
      
      return cell
      }
      

      【讨论】:

        【解决方案5】:
        var frndsName = ["Vanitha","Ilakkiya","Parveen","Divya","Seetha","Madhavi","Ashwini","Sangeetha","Swathi","Don","Priyanka","Tamilselvi","Premlatha","Prashanthi","Rekha","Ajitha","Praveena","Indhusree","Nisha","Priya","Lavanya","Sandhiya","Gejalakshmi","Pavithra","Abinaya"]
            let sections = ["*","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","#"]
            var dividedArray:NSMutableArray = []
        
            override func viewDidLoad() {
                super.viewDidLoad()
                for i in sections{
                    let dummyArray:NSMutableArray = []
                    for j in frndsName{
                        if  i.first!  == j.first! {
                          dummyArray.add(j)
                        }
                    }
                   dividedArray.add(dummyArray)
                }
            }
        
            override func didReceiveMemoryWarning() {
                super.didReceiveMemoryWarning()
            }
            func numberOfSections(in tableView: UITableView) -> Int {
             return 26
            }
        
            func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                return (dividedArray[section] as! NSMutableArray).count
            }
        
            func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                let cell = tableView.dequeueReusableCell(withIdentifier: "cell")
                let dummyArray = dividedArray[indexPath.section] as! NSMutableArray
                cell?.textLabel?.text = dummyArray[indexPath.row] as? String
        
                return cell!
                  }
            func sectionIndexTitles(for tableView: UITableView) -> [String]? {
                return self.sections
            }
            func tableView(_ tableView: UITableView, sectionForSectionIndexTitle title: String, at index: Int) -> Int {
                return index
            }
            internal func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
                return self.sections[section] as String
            }
        }
        

        【讨论】:

          【解决方案6】:

          如果您的数据数组未预定义,这里有一种方法可以实现相同的目的。

          假设我们的类是ViewController

          class ViewController: UIViewController {
          
               var contactDictionary = [String: [Contact]]() //Contact is a model, it has firstName and lastName properties
               var keys = [String]()
               var alphabets = (97...122).map { "\(Character(UnicodeScalar.init($0)))" }.map { $0.uppercased() } //Populating alphabets
               ... // other properties
          
          
              override func viewDidLoad() {
                  super.viewDidLoad()
                  //set delegate and register cell for your tableView
                  self.setContacts()
              }
          
              private func setContacts() {
                   //Loop through your array, take the firstName, and the first character of that string.
                   //Check the uppercase value of that character, if it's an alphabet or not, otherwise, we'd place "#" for the names starting with a number in the header.
          
                   var temp = [String: [Contact]]() //A temporary dictionary
                   for contact in self.contacts {
                       if let firstName = contact.firstName, !firstName.isEmpty { //In my case, the firstName is an optional string
                          let firstChar = "\(firstName.first!)".uppercased()
                          if alphabets.contains(firstChar) {
                              var array = temp[firstChar] ?? []
                              array.append(contact)
                              temp[firstChar] = array
                          } else {
                              var array = temp["#"] ?? []
                              array.append(contact)
                              temp["#"] = array
                          }
                      }
                  }
                  self.keys = Array(temp.keys).sorted() //Populating and sorting all the keys alphabetically.
                  for key in self.keys { self.contactDictionary[key] = temp[key] }
                  //reload table
              }
          }
          
          extension: ViewController: UITableViewDelegate, UITableViewDataSource {
          
              func numberOfSections(in tableView: UITableView) -> Int {
                  return self.contactDictionary.count
              }
          
              func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                  return self.contactDictionary[keys[section]]?.count ?? 0
              }
          
              func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
          
                  let key = self.keys[indexPath.section]
                  let cell: //dequeue your cell here.
                  if let row = self.contactDictionary[key]?[indexPath.row] {
                      cell.display(with: row) //Bind your cell's outlets with the properties
                      return cell
                  }
          
                  //handle error
              }
          
              func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                  let key = self.keys[indexPath.section]
                  if let row = self.contactDictionary[key]?[indexPath.row] {
                      //handle selection.
                  }
              }
          
              func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { //You can use viewForHeaderInSection either.
                  return self.keys[section]
              }
          
          }
          

          【讨论】:

            【解决方案7】:
            var nameList = ["Abc","Bbc","Cbc",......]//whatever it is
            var arrNameList = [[nameList]]()
            var str = String()
            
            override func viewDidLoad() {
            
              str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
            
              for i : Int in 0 ..< (str.count) {
                  var arr = [nameList]()
                    for j : Int in 0 ..< nameList.count {
                      let name = nameList[j]
                      let index = str.index(str.startIndex, offsetBy: i)
                      let char = str[index]
                      if name.first == char {
                          arr.append(name)
                      }
                  }
                  arrNameList.append(arr)
               }
            }
            
            func numberOfSections(in tableView: UITableView) -> Int {
              return arrNameList.count
            }
            
            func tableView(_ tableView: UITableView, titleForHeaderInSection 
            section: Int) -> String? {
              let index = str.index(str.startIndex, offsetBy: section)
              let char = str[index]
              return char
            }
            
            func tableView(_ tableView: UITableView, numberOfRowsInSection 
            section: Int) -> Int {
              return arrNameList[section].count
            }
            
            func tableView(_ tableView: UITableView, heightForHeaderInSection 
            section: Int) -> CGFloat {
              return 40
            }
            
            func tableView(_ tableView: UITableView, heightForRowAt indexPath: 
            IndexPath) -> CGFloat {
              return 40
            }
            
            func tableView(_ tableView: UITableView, cellForRowAt indexPath: 
            IndexPath) -> UITableViewCell {
            
              let cell = tableView.dequeueReusableCell(withIdentifier: "cell", 
              for: indexPath) as! NameListTableViewCell
            
              let name = arrNameList[indexPath.section][indexPath.row]
              cell.nameLbl.text = name
            
              cell.selectionStyle = .none
              return cell
            }
            

            【讨论】:

              猜你喜欢
              • 2020-05-08
              • 1970-01-01
              • 1970-01-01
              • 2018-12-26
              • 2015-10-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多