Как передать состояние UISwitch в ячейке прототипа обратно в UITableView - PullRequest
0 голосов
/ 23 апреля 2019

У меня есть UIS-переключатель в ячейке прототипа, который я не могу понять, как передать состояние обратно в мой UITableView. Мне нужно состояние переключателя, переданного обратно, чтобы обновить объект, чтобы отразить новое состояние.

Я пробовал следующие вопросы, но они оба в Задаче C (я едва могу написать Swift, поэтому я изо всех сил пытаюсь понять, как их адаптировать) Доступ к UISwitch в ячейке прототипа и Как получить состояние UISwitch в каждой из моих ячеек UITableView?

В настоящее время я пытаюсь заставить это решение работать.

Вот параметры для построения ячейки в UITabelView:

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        guard let cell = tableView.dequeueReusableCell(withIdentifier: "ProgrammeToggleTableViewCell", for: indexPath) as? ProgrammeToogleTableViewCell else { return UITableViewCell() }

        cell.setTitle(text: programmes[indexPath.row].name)

        cell.programmeToggle.tag = indexPath.row
        print(cell.programmeToggle.tag)
        cell.programmeToggle.isOn = programmes[indexPath.row].active
        cell.programmeToggle.addTarget(self, action: #selector(ProgrammeTableViewController.switchAtValueChanged(programmeToggle: UISwitch, indexPath: IndexPath)), for: UIControl.Event.valueChanged)

        return cell
    }

Позже я пытаюсь получить доступ к коммутатору, используя следующее:

    @objc func switchAtValueChanged(programmeToggle: UISwitch, indexPath: IndexPath) {

        if programmeToggle.tag == 1 {
            var programmes[indexPath.row].active = UISwitch.isOn
            print(programmes[1].active)
        }
    }

programmes - массив объектов.

Строка var programmes[indexPath.row].active = UISwitch.isOn в настоящее время дает мне следующие ошибки: Consecutive statements on a line must be separated by ';' Type annotation missing in pattern Value of type '[Int]' has no member 'active'

Я бы хотел использовать состояние переключателя для редактирования значения одного из объектов в массиве programmes. Поскольку я неопытен в Swift, я не знаю, лаю ли я не на том дереве или это реальное решение при работе.

Спасибо за любую помощь, рад предоставить любую дополнительную информацию, если это необходимо.

Ответы [ 3 ]

1 голос
/ 23 апреля 2019

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

 class ProgrammeToogleTableViewCell: UITableViewCell {

   @IBOutlet weak var switchUI: UISwitch!

   // callback to get action of switch status
   var callBackSwitchState:((Bool) -> (Void))?

  // Create action for value change event on switch
   @IBAction func switchAtValueChanged(programmeToggle: UISwitch) {
     callBackSwitchState?(programmeToggle.isOn)
   }
}

Теперь в вашем методе источника данных cellForRowAt вам нужно установить значение для этого обратного вызова, который вы только что создали, чтобы получить статусдля вашего коммутатора:

В вашем классе просмотра таблицы:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> 
  UITableViewCell {
   guard let cell = tableView.dequeueReusableCell(withIdentifier: 
     "ProgrammeToggleTableViewCell", for: indexPath) as? ProgrammeToogleTableViewCell 
     else { return UITableViewCell() }
    cell.tag = indexPath.row

    // Implement the callback to get the status of switch:
    cell.callBackSwitchState = { isOn in
    print("Your Switch status = \(isOn)")

    // isOn is your switch status. You can update your object here.
   }

 // Your other code here ....
 return cell
}
1 голос
/ 23 апреля 2019

Это не так тривиально, как вы попробовали.Когда вы удаляете из очереди ячейку табличного представления, это означает, что она либо создаст новую ячейку, либо повторно использует старую.Например, у вас есть 100 ячеек, но вы можете видеть только 10 одновременно.Когда пользователь прокручивает страницу вниз, первая ячейка исчезает, а затем снова используется как 11-я ячейка.Итак, это физически одна и та же клетка.И, если вы добавите target-selector на его переключатель, это будет означать, что теперь у вас есть 2 действия с этим переключателем.Но, как вы, вероятно, выяснили, у вас все равно есть другие проблемы в этом случае (например, невозможность вставить путь индекса в метод).

Таблицу нужно использовать только как представление данных.Таким образом, вы должны изменить данные в другом месте.

Самое простое решение в вашем случае - добавить свой класс в саму ячейку.Просто назначьте его в ячейке для метода строки:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    guard let cell = tableView.dequeueReusableCell(withIdentifier: "ProgrammeToggleTableViewCell", for: indexPath) as? ProgrammeToogleTableViewCell else { return UITableViewCell() }
    cell.programme = programmes[indexPath.row]
    return cell
}

Теперь поместите всю логику внутри ячейки, например, например:

var programme: Programme? {
    didSet {
        refresh()
    }
}
func refresh() {
    guard let programme = programme else { return }
    programmeToggle.isOn = programme.active
}

@IBAction private func switchToggled() {
    self.programme?.active = programmeToggle.isOn
}

Теперь действие переключателя влияет на назначенную программу.В вашем случае этого должно быть достаточно.

В качестве альтернативы вам во многих случаях необходимо использовать делегатов.Контроллер вашего вида определит протокол о том, что переключатель был переключен, и вы назначите его своей ячейке:

cell.progremmeID = progremme.id
cell.delegate = self
return cell

, а затем протокол:

func programmeCell(_ sender: ProgrammeToogleTableViewCell, didToggleProgremme programmeID: String, toActive flag: Bool) {
    programmes.first(where: { $0.id == programmeID })?.active = flag
}
0 голосов
/ 23 апреля 2019

просто удалите переменную, следующую строку-

var программы [indexPath.row] .active = UISwitch.isOn

...