Swift 2.2 - 如何在特定段(UISegmentedControl)下创建两个或更多部分?

Swift 2.2 - How to create two and more sections under specific segment (of UISegmentedControl)?

我正在构建我的第一个 iOS 应用程序,我想创建以下内容:

我能够创建 UITableView,例如segment Movie 显示带有单元格的一个部分(电影)。但是,我不知道如何在一个段下创建多个段。

仅供参考,用户不会修改或删除部分和单元格。

我试图在网上找到答案,但并没有真正成功。

谢谢大家的帮助!

编辑: 我现在的项目中有一些代码片段(部分和对象的名称不同——这只是一个例子)。有两个主要问题: 1. 每个段只显示一个部分(同名)。我打算稍后添加更多 sections/objects。我应该在 ViewController.swift 中进行哪些更改以显示更多部分? 2. 我不得不重复 ViewController.swift 中的部分(例如 let pulpFiction: [String] =... )来填充单元格,因为我不知道如何在 SectionsData.swift 中访问它们。我知道必须有更好的方法来做到这一点 - 请问,您能提供建议吗?

Section.swift

struct Section {
    var heading : String
    var items : [String]

    init(title: String, objects : [String]) {

        heading = title
        items = objects
    }
}

SectionsData.swift

var segment1Count: Int!
var segment2Count: Int!
var segment3Count: Int!

let section1 = Section(title: "Pulp Fiction", objects: ["John Travolta", "Quentin Tarantino", "Uma Thurman", "Samuel L. Jackson"])
let section2 = Section(title: "12 Angry Men", objects: ["Henry Fonda", "Lee J. Cobb", "Martin Balsam", "John Fiedler"])
let section3 = Section(title: "Fight Club", objects: ["Edward Norton", "Brad Pitt"])


class SectionsData {

    func getSectionsFromData() -> [Section] {

        var sectionsArray = [Section]()

        sectionsArray.append(section1)
        sectionsArray.append(section2)
        sectionsArray.append(section3)

        segment1Count = section1.items.count
        segment2Count = section2.items.count
        segment3Count = section3.items.count

        return sectionsArray
    }
}

ViewController.swift

var sections: [Section] = SectionsData().getSectionsFromData()

let pulpFiction: [String] = ["John Travolta", "Quentin Tarantino", "Uma Thurman", "Samuel L. Jackson"]
let angryMen: [String] = ["Henry Fonda", "Lee J. Cobb", "Martin Balsam", "John Fiedler"]
let fightClub:  [String] = ["Edward Norton", "Brad Pitt"]

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        var sectionsNumber = 0

        switch(segmentedControlOutlet.selectedSegmentIndex) {

        case 0:
            sectionsNumber = sections.count
            break

        case 1:
            sectionsNumber = 1
            break

        case 2:
            sectionsNumber = 1
            break

        case 3:
            sectionsNumber = 1
            break

        default:
            break
        }

        return sectionsNumber
    }


internal func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    var numberOfRows: Int!

    switch(segmentedControlOutlet.selectedSegmentIndex) {

    case 0:
        numberOfRows = sections[section].items.count
        break

    case 1:
        numberOfRows = segment1Count
        break

    case 2:
        numberOfRows = segment2Count
        break

    case 3:
        numberOfRows = segment3Count
        break

    default:
        break
    }

    return numberOfRows
}


  func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        var sectionHeader: String!

        switch(segmentedControlOutlet.selectedSegmentIndex) {

        case 0:
            sectionHeader = sections[section].heading
            break

        case 1:
            sectionHeader = segmentedControlOutlet.titleForSegmentAtIndex(1)
            break

        case 2:
            sectionHeader = segmentedControlOutlet.titleForSegmentAtIndex(2)
            break

        case 3:
            sectionHeader = segmentedControlOutlet.titleForSegmentAtIndex(3)
            break

        default:
            break
        }

        return sectionHeader
    }

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("prototypeCell", forIndexPath: indexPath)

    switch(segmentedControlOutlet.selectedSegmentIndex) {

    case 0:
        cell.textLabel!.text = sections[indexPath.section].items[indexPath.row]
        break
    case 1:
        cell.textLabel!.text = pulpFiction[indexPath.row]
        break

    case 2:
        cell.textLabel!.text = angryMen[indexPath.row]
        break

    case 3:
        cell.textLabel!.text = fightClub[indexPath.row]
        break

    default:
        break
    }

    return cell
}

基于您的 Section 结构的非常简单的示例:

该示例仅影响 ViewController class 并且 UISegmentedControl 实例应该有两个部分:Movies(索引 0)和 Music (索引 1)

  • 为方便起见,为部分索引声明一个枚举

    enum SectionIndex : Int {
      case Movies, Music
    }
    
  • 声明数据源数组

    var sections = [Section]()
    
  • 创建一个根据索引

    填充sections数组的方法
      func updateSections(index : SectionIndex)
      {
        sections.removeAll()
        switch index {
        case .Movies:
          sections.append(Section(title: "Pulp Fiction", objects: ["John Travolta", "Quentin Tarantino", "Uma Thurman", "Samuel L. Jackson"]))
          sections.append(Section(title: "12 Angry Men", objects: ["Henry Fonda", "Lee J. Cobb", "Martin Balsam", "John Fiedler"]))
          sections.append(Section(title: "Fight Club", objects: ["Edward Norton", "Brad Pitt"]))
        case .Music:
          sections.append(Section(title: "The Beatles", objects: ["John Lennon", "Paul McCartney", "George Harrison", "Ringo Starr"]))
          sections.append(Section(title: "Genesis", objects: ["Phil Collins", "Mike Rutherford", "Tony Banks"]))
          sections.append(Section(title: "Queen", objects: ["Freddie Mercury", "Brian May", "Roger Taylor", "John Deacon"]))
        }
        tableView.reloadData()
      }
    
  • viewDidLoad中使用默认索引调用updateSections

    override func viewDidLoad() {
      super.viewDidLoad()
      updateSections(.Movies)
    }
    
  • 将分段控件的动作valueChanged连接到这个IBAction

    @IBAction func didChangeValue(control : UISegmentedControl)
    {
      updateSections(SectionIndex(rawValue:control.selectedSegmentIndex)!)
    }
    
  • 这些是table视图数据源和委托方法

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
      return sections.count
    }
    
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      let section = sections[section]
      return section.items.count
    }
    
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      let cell = tableView.dequeueReusableCellWithIdentifier("prototypeCell", forIndexPath: indexPath)  
      let section = sections[indexPath.section]
      cell.textLabel!.text = section.items[indexPath.row]
      return cell
    }
    
    override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
      return sections[section].heading
    }
    

现在,当您点击分段控件时,sections 数组会相应更新并重新加载 table 视图。然而,使用 Core DataNSFetchedResultController 会更有效率。您只需更改获取请求并重新获取数据即可。