2016-09-10 2 views
2

У меня есть UIButton, для которого я хочу переключить заголовок и цвет, когда я его нажимаю. Кнопка должна иметь три состояния: ежедневно, ежемесячно и ежегодно.Переключение между тремя состояниями с UIButton

Сейчас у меня есть это решение, которое не кажется, что элегантный:

if sender.currentTitle == "Daily" { 
    sender.setTitle("Monthly", for: .normal) 
    sender.setTitleColor(UIColor(hex: "FB967F"), for: .normal) 
} else if sender.currentTitle == "Monthly" { 
    sender.setTitle("Yearly", for: .normal) 
    sender.setTitleColor(UIColor(hex: "A395CE"), for: .normal) 
} else if sender.currentTitle == "Yearly" { 
    sender.setTitle("Daily", for: .normal) 
    sender.setTitleColor(UIColor(hex: "75CFF8"), for: .normal) 
} 

есть более удобный способ сделать это в Swift?

ответ

2

объявить counter переменных и два массива

var counter = 0 
let titleArray = ["Daily", "Monthly", "Yearly"] 
let colorArray = ["FB967F", "A395CE", "75CFF8"] 

затем увеличить счетчик (держать его в диапазоне 0 ... 2 через оператор по модулю) и получить заголовок и значение цвета из массивов

counter = (counter + 1) % titleArray.count 
sender.setTitle(titleArray[counter], for: .normal) 
sender.setTitleColor(UIColor(hex: colorArray[counter]), for: .normal) 
3

Использовать перечисление Это лучшее для поддержания состояния. Сохраняет ваш код в чистоте и читаемости.

enum ButtonState { 
    case daily 
    case monthly 
    case yearly 

    mutating func next(forButton button:UIButton) { 
     switch (self) { 
     case .daily: 
      self = .monthly 
     case .monthly: 
      self = .yearly 
     case .yearly: 
      self = .daily 
     } 

     button.setTitle(self.getTitle(), forState: .Normal) 
     button.setTitleColor(UIColor(hex: self.getTitleColorHex()), forState: .Normal) 
    } 

    private func getTitle() -> String { 
     switch (self) { 
     case .daily: 
      return "Daily" 
     case .monthly: 
      return "Monthly" 
     case .yearly: 
      return "Yearly" 
     } 
    } 

    private func getTitleColorHex() -> String { 
     switch (self) { 
     case .daily: 
      return "FB967F" 
     case .monthly: 
      return "A395CE" 
     case .yearly: 
      return "75CFF8" 
     } 
    } 
} 

var currentButtonState = ButtonState.daily 

func changeButtonState(forButton button:UIButton) { 
    currentButtonState.next(forButton: button) 
} 
+0

Вы превратили 10 строк кода в 40. Это более читаемо? :) – Grimxn

+2

lol. все о абстракции, вы можете выбрать создание массивов из двух параметров и просто использовать rawvalue из enum для получения результатов, что уменьшит его до половины Я просто написал его полностью, чтобы дать более четкое представление о том, что продолжается. Подумайте о коде контроллера вида - всего 2 строки. ;), а также способность абстрагироваться и инкапсулировать реализацию всего состояния. – vj9

0

Я не думаю, что ваш код так безвкусное - три состояния не является настолько сложным, что их трудно читать (что на самом деле проблема с безвкусным кодом), однако, если это было более трех, вы определенно хотите что-то опрятное. Как насчет использования словарного перевода:

func newButtonState(sender: UIButton) { 
    let buttonDict = ["Yearly": (UIColor.red, "Daily"), 
         "Monthly": (UIColor.green, "Yearly"), 
         "Daily": (UIColor.yellow, "Monthly")] 
    if let t = sender.currentTitle, let n: (UIColor, String) = buttonDict[t] { 
     sender.setTitle(n.1, for: .normal) 
     sender.setTitleColor(n.0, for: .normal) 
    } 
} 
+0

Просто позвоните в функцию - кнопка «Состояние» - это ее название, а функция циклически проходит через заголовки ... – Grimxn

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