Swift 4 - Создание общей функции для нескольких кнопок

Мне интересно, есть ли более эффективный способ кодировать действие, которое является таким же, за исключением того, какая кнопка была нажата и к какому элементу в структуре она относится. По сути, у меня есть структура из 10 переменных, все из которых имеют логический тип, и у меня есть 10 кнопок. Когда пользователь нажимает кнопку, я хочу проверить, была ли она уже нажата (используя структуру), а затем изменить фон кнопки в зависимости от состояния и изменить состояние. Я скопировал свой текущий код для одной из кнопок, но подумал, что смогу избежать этого 10 раз!

@IBAction func architectureButtonPressed(_ sender: Any) {

        if myInterests.architecture {

             myInterests.architecture = false
             architectureButton.setBackgroundImage(imageUncheckedNarrow, for: .normal)

        } else {

            myInterests.architecture = true
            architectureButton.setBackgroundImage(imageCheckedNarrow, for: .normal)
        }


    }

3 ответа

Решение

Ну, один простой способ состоит в том, чтобы каждая кнопка UIButton указывала на один и тот же метод ArchitectureButtonPressed IBAction. Поскольку нажатая кнопка передается в метод (отправитель), вы можете обратиться к ее свойству тега, чтобы узнать, какой индекс в вашей структуре должен быть обновлен. (И тогда вы можете изменить свою структуру, чтобы хранить массив из 10 bools, но только на ваше усмотрение).

Затем для каждого UIButton, будь то программно в раскадровке или перо, вы должны присвоить соответствующее значение индекса полю тега кнопки.

Мое предложение состоит в том, чтобы управлять изображениями в Интерфейсном Разработчике через State Config (Default/Selected)

Затем назначьте уникальный тег, начиная с 100, каждой кнопке и установите isSelected значение в IBAction для соответствующего члена структуры в switch заявление:

@IBAction func buttonPressed(_ sender: UIButton) {
    switch sender.tag {
    case 100: myInterests.architecture = sender.isSelected
    case 101: myInterests.art = sender.isSelected

    ...
    default: break
    }

}

В качестве альтернативы можно использовать родной KVC Swift с WriteableKeypath

let keypaths : [WritableKeyPath<Interests,Bool>] = [\.architecture, \.art, \.fashion, \.history, \.localCulture, \.music, \.nature, \.shopping, \.sport, \.anything]

@IBAction func buttonPressed(_ sender: UIButton) {
    let index = sender.tag - 100
    let keypath = keypaths[index]
    myInterests[keyPath: keypath] = sender.isSelected
}
  1. Создай свой IBOutlet для каждой кнопки.

  2. Создайте массив и сохраните все кнопки, например: var arrayButtons : [UIButton] = []

    arrayButtons.append [Button1]

    arrayButtons.append [button2]

    ...

  3. Создать массив логических значений для хранения true/false: var arrayBools : [Bool] = [] и инициализировать, если какое-то значение.

Обратите внимание, что индексы arrayButtons и arrayBools должны быть связаны друг с другом.

  1. Создать функцию выбора для прослушивания сенсорных кнопок.

    button.addTarget(self, action: #selector(my_func), for: .touchUpInside)
    
    @objc func my_func(_ sender : UIButton) {
    
    for i in 0...arrayButtons.size-1 {
        if arrayButtons[i] == sender {
            if arrayBooleans[i] {
                arrayBooleans[i] = false
                arrayButtons[i].setImage()
            } else {
                arrayBooleans[i] = true
                arrayButtons[i].setImage()
            }
        }
      }
    }
    
Другие вопросы по тегам