将UITableView分类为几个部分

时间:2016-04-24 19:10:33

标签: ios swift uitableview cocoa-touch

我是swift& amp;的新手Xcode(通过教程和stackoverflow自学)。我已经编写了一些代码,这些代码将位置添加到TableView中的列表中,现在我尝试将这些位置列表分类。

具体来说,我有一个ViewController,我在其中输入名称,邻居和朋友(所有字符串),这会在我的TableView底部添加一个Place。

我想按邻域对这个地方列表进行分组,并使用邻域字符串作为节标题,在一个部分中一起显示同一邻域中的所有地点。

我已经关闭,但我没有正确索引我的部分。 indexPath.section我相信是我所缺少的......

到目前为止,我在TableViewController中有这段代码:

// MARK: Properties

var places = [Place]()

override func viewDidLoad() {
    super.viewDidLoad()

    // Use the edit button item provided by the table view controller.
    navigationItem.leftBarButtonItem = editButtonItem()

    // Load any saved places, otherwise load sample data.
    if let savedPlaces = loadPlaces() {
        places += savedPlaces
    }

    else {
        // Load the sample data.
        loadSamplePlaces()
    }

    // Sort by neighborhood
    places.sortInPlace { (place1, place2) -> Bool in
        return place1.neighborhood < place2.neighborhood
    }
}

// MARK: Getting Count, Number and Name of Neighborhoods
func getCountForNeighborhood(neighborhood:String) -> Int {
    return places.filter { (place) -> Bool in
        return place.neighborhood == neighborhood
    }.count
}

func getNumberOfNeighborhoods() -> Int {
    var neighborhoodCount = 0
    var neighborhoodPrev = "Not a real neighborhood"
    for place in places {
        if place.neighborhood != neighborhoodPrev {
            neighborhoodCount += 1
        }
        neighborhoodPrev = place.neighborhood
    }
    return neighborhoodCount
}

func getNeighborhoodForSection(section:Int) -> String {
    var previousNeighborhood:String = "Not a real neighborhood"
    var currentIndex = -1

    for place in places {

        if(place.neighborhood != previousNeighborhood) {
            currentIndex += 1
        }
        if(currentIndex == section){
            return place.neighborhood
        }
        previousNeighborhood = place.neighborhood
    }

    return "Unknown"
}

func loadSamplePlaces() {

    let place1 = Place(name: "Motorino", neighborhood: "East Village", friend: "Maggles")!
    let place2 = Place(name: "Bar Primi", neighborhood: "Lower East Side", friend: "Em")!
    let place3 = Place(name: "El Carino", neighborhood: "Williamsburg", friend: "Ruby")!

    places += [place1, place2, place3]
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    //alter this for To Try, Been To sections =2
    return getNumberOfNeighborhoods()
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows

    let neighborhood = getNeighborhoodForSection(section)
    return getCountForNeighborhood(neighborhood)
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    // Table view cells are reused and should be dequeued using a cell identifier.
    let cellIdentifier = "PlaceTableViewCell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! PlaceTableViewCell

    // Fetches the appropriate place for the data source layout.

    let place = places[indexPath.row]

    cell.placeLabel.text = place.name
    cell.neighborhoodLabel.text = place.neighborhood
    cell.friendLabel.text = place.friend

    return cell
}

//Add section headers
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return getNeighborhoodForSection(section)

}

我非常确定我的cellForRowAtIndexPath方法存在问题。我想我错过了一些代码来正确地将数据索引到各个部分......

当前版本显示this

2 个答案:

答案 0 :(得分:0)

你把各个部分搞得一团糟。

在方法tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)中,您将根据indexPath的行从places数组中获取数据。 但你根本不“谈论”部分。这就是为什么你告诉数据源代表获取这两个地方对象的数据而不管它要求你的部分。 你已经建立了一个像这样的关系风格的数据结构:

neighbourhood1 - place1
neighbourhood1 - place2
neighbourhood2 - place3
neighbourhood2 - place4
neighbourhood3 - place5
neighbourhood3 - place6

相信我,将这个数据结构与UITableView数据源概念联系起来真的很难,因为很难从单个数据中确定部分索引。 尝试在这样的树中安排您的数据:

neighbourhood1:
 - place1
 - place2
neighbourhood2:
 - place3
 - place4
neighbourhood3:
 - place5
 - place6

在数组数组中,然后它会很简单,因为indexPath对(section,row)将匹配places[section][row]的索引:

neighbourhood1: (section 0)
 - place1 (path 0.0)
 - place2 (path 0.1)
neighbourhood2: (section 1)
 - place3 (path 1.0)
 - place4 (path 1.1)
neighbourhood3: (section 2)
 - place5 (path 2.0)
 - place6 (path 2.1)

答案 1 :(得分:0)

我同意另一个答案:如果您将数据存储在由邻居组织的二维数组中,然后排在第二位,然后将数据存储为:

,这将更容易
let place = places[indexPath.section, indexPath.row];

但是,根据您的具体问题和当前代码,我在这里看到两件事。首先,您的示例数据每个邻域只有一个项目,但您的表格每个邻域显示两行。这表示当我们预期numberOfRowsInSection函数为1时,getNeighborhoodForSection函数返回2.请确保getCountForNeighborhood返回正确的部分。然后看看getNeighborhoodForSection为什么不为每个部分返回1。 (顺便说一句,你可能已经知道了这一点,但是cellForRowAtIndexPath假设你的数据总是按邻域排序。如果你不按顺序插入一个新邻居,你就会遇到问题。)

其次,indexPath.row您总是按indexPath.row号码提取数据。当您为每个邻域输入此函数时,places编号将始终从0重新开始,每个部分(邻域)。因此,您将从cellForRowAtIndexPath(Motorino)中拉出第1项,作为每个部分的第一行。这就是为什么你会在每个部分看到相同的重复列表的原因。

每个社区有正确的行数后,在getNeighborhoodForSection(index.section);中您需要:

  1. 使用places
  2. 获取index.section的邻域
  3. 搜索neighborHoodStartIndex,直至找到该邻居并保存起点的索引,我将调用let place = places[neighborHoodStartIndex + indexPath.row]
  4. component
  5. 出于调试目的,我建议在每个社区中制作不同数量的样本位置。当您期望每个部分中有不同数量的行时,它会更容易发现问题模式。