Как установить фильтр по объекту в tableview без строки поиска?

#ios #swift #sorting #uitableview #filter

Вопрос:

У меня есть просмотр таблицы, и я хочу добавить кнопку, которая будет фильтровать данные по заданной опции. Например, я хочу отображать в таблице только те данные, которые содержат «Посещающих». Вот мой код:

  func filterBy(){
    let addEvent = UIAlertController(title: "Sort by:", message: "Sort guests", preferredStyle: .alert)
    let subview = (addEvent.view.subviews.first?.subviews.first?.subviews.first!)! as UIView
    let shapes = UIView()
    shapes.layer.cornerRadius = 30
    shapes.layer.borderWidth = 5
    shapes.layer.borderColor = #colorLiteral(red: 0.9843137255, green: 0.8196078431, blue: 0.8509803922, alpha: 1)
    subview.backgroundColor = #colorLiteral(red: 0.9607843137, green: 0.9333333333, blue: 0.9176470588, alpha: 1)
    subview.tintColor = #colorLiteral(red: 0.9843137255, green: 0.8196078431, blue: 0.8509803922, alpha: 1)
    addEvent.view.tintColor = #colorLiteral(red: 0.4431372549, green: 0.4431372549, blue: 0.4431372549, alpha: 1)
    
    let addSortAction = UIAlertAction(title: "Attending", style: .default) { (action) in
        let sortedBy: () = self.guestsList.sort(by: { $0.attendingStatus ?? "" > $1.attendingStatus ?? ""})
       print(sortedBy)
        self.guestsTableView.reloadData()
    }
    let cancelAction = UIAlertAction(title: "Cancel", style: .default)
    addEvent.addAction(addSortAction)
    addEvent.addAction(cancelAction)
    present(addEvent, animated: true, completion: nil)
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return guestsList.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "guestCell", for: indexPath) as! GuestTableViewCell
    let guest: GuestModel
    guest = guestsList[indexPath.row]
    
    cell.guestNameLabel.text = guest.guestName!   " "   guest.guestFamilyName!
    cell.attendingLabel.text = guest.attendingStatus
    cell.menuLabel.text = guest.menuStatus
    cell.ageLabel.text = guest.ageStatus
    cell.tableLabel.text = guest.tableNo
    
    return cell
}
 

Модель:

 class GuestModel {
    
    var guestName: String?
    var attendingStatus: String?
    var menuStatus: String?
    var ageStatus: String?
    var tableNo: String?
    var id: String?
    var guestFamilyName: String?
    var guestPhoneNumber: String?
    var guestEmail: String?
}
 

введите описание изображения здесь

Комментарии:

1. Можете ли вы опубликовать источник данных представления таблицы и методы делегирования? А ваш класс модели элемента списка? Я не понимаю, почему вы создаете диалоговое окно для сортировки своих значений, в то время как вам нужно их отфильтровать.

2. @luca_999 Сначала я пытался отсортировать, но теперь мне нужно отфильтровать значения, и поскольку я новичок в swift, я не знаю, как их отфильтровать.

3. Хорошо, все же, можете ли вы опубликовать источник данных представления таблицы и методы делегирования? А ваш класс модели элемента списка?

4. @luca_999 Я отредактировал вопрос. Есть источник данных и делегат.

Ответ №1:

Для достижения желаемого вы можете использовать три глобальные переменные

  1. Полный список, который вы инициализируете в начале (список гостей)
  2. Отфильтрованный список, используемый в качестве источника данных табличного представления (filteredGuestsList)
  3. Строка поиска, которая применяет фильтр к списку (в моем случае считается, что вы примените фильтр к guestName свойству)

filterBy Методу нужно только обновить искомое значение, и его нужно вызывать каждый раз, когда вы хотите очистить или обновить искомое значение.

 private var guestsList = [GuestModel]() {
    didSet {
        filteredGuestsList = guestsList
    }
}
private var filteredGuestsList = [GuestModel]() {
    didSet {
        guestsTableView.reloadData()
    }
}
private var search = "" {
    didSet {
        filteredGuestsList = search != "" ? guestsList.filter {
            $0.guestName.uppercased().contains(searchText.uppercased())
        } : guestsList
    }
}

func filterBy(_ text: String) {
    search = text
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return filteredGuestsList.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "guestCell", for: indexPath) as! GuestTableViewCell
    let guest = filteredGuestsList[indexPath.row]
    
    cell.guestNameLabel.text = guest.guestName!   " "   guest.guestFamilyName!
    cell.attendingLabel.text = guest.attendingStatus
    cell.menuLabel.text = guest.menuStatus
    cell.ageLabel.text = guest.ageStatus
    cell.tableLabel.text = guest.tableNo
    
    return cell
}