2016-04-24 6 views
2

Я новичок в swift & Xcode (обучение самому себе с помощью учебников и stackoverflow). Я написал код, который добавляет места в список в TableView, и теперь я пытаюсь сортировать этот список мест в разделах.Сортировка UITableView в разделы

В частности, у меня есть ViewController, где я ввожу имя, окрестности и друга (все строки), и это добавляет место в нижней части моего TableView.

Я хочу сгруппировать этот список мест по соседству и отобразить все места в том же районе вместе в разделе, используя строку окрестности в качестве заголовка раздела.

Я близко, но я не правильно индексирую свои разделы. 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

ответ

0

Вы напутали с разделами.

В методе tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) вы берете данные из массива мест на основе строки indexPath. Но вы вообще не говорите о разделах. Вот почему вы передаете делегату источника данных данные данных этих 2-х объектов независимо от раздела, которое он просит. Вы сделали структуру данных в реляционном стиле, как это:

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

И поверьте мне, это очень трудно для взаимодействия этой структуры данных с концепцией источника UITableView данных, потому что это действительно трудно определить индекс раздела из отдельных данных. Попробуйте организовать ваши данные в виде дерева, как это:

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

В массиве массивов, и тогда это будет просто, вызвать indexPath пару (раздел, строку) будет соответствовать показателям вашей 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) 
0

Я согласен с другим ответом: это будет проще, если ваш магазин ваши данные в двумерном массиве организованной окрестности первого, а затем поместить второй, а затем получить доступ к данным, как:

let place = places[indexPath.section, indexPath.row]; 

Однако, к вашим конкретным вопросам и текущему коду, я вижу здесь две вещи. Во-первых, ваши данные образца имеют один элемент для каждого района, но ваша таблица показывает две строки для каждой окрестности. Это означает, что ваша функция numberOfRowsInSection возвращает 2, когда мы ожидаем, что она будет 1. Убедитесь, что ваш getNeighborhoodForSection возвращается в нужную секцию. Затем посмотрите, почему getCountForNeighborhood не возвращает 1 для каждой секции. (В стороне, вы, вероятно, уже знаете это, но getNeighborhoodForSection предполагает, что ваши данные всегда сортируются по соседству. Если вы введете новый район из строя, у вас возникнут проблемы).

Во-вторых, cellForRowAtIndexPath вы всегда извлекаете данные по номеру indexPath.row.Когда вы вводите эту функцию для каждой окрестности, номер indexPath.row всегда будет перезагружен на 0 для каждого раздела (окрестности). И поэтому вы вытащите 1-й предмет из places (Motorino) для первой строки в каждом разделе. Вот почему вы видите тот же список мест, которые повторяются в каждом разделе.

После того, как у вас есть нужное количество строк в окрестности, в cellForRowAtIndexPath вам нужно:

  1. Получить окрестности для index.section с помощью getNeighborhoodForSection(index.section);
  2. Поиск по places, пока вы не обнаружите, что окрестности и сохранить индекс начальной точки, которую я буду называть neighborHoodStartIndex
  3. let place = places[neighborHoodStartIndex + indexPath.row]

Для целей отладки, я предлагаю сделать другое количество мест для образцов в каждом районе. Будет немного легче выявить шаблоны проблем, если вы ожидаете различного количества строк в каждом разделе.

Смежные вопросы