Перечисление Swift NSPopUpButton - PullRequest
       49

Перечисление Swift NSPopUpButton

0 голосов
/ 04 февраля 2019

Я реализую NSPopUpButton (для приложения MacOS, использующего Swift), как на рисунке:

enter image description here

И у меня есть следующеекод, который на самом деле работает:

enum Importance: Int8 {
case EXTREMELY_IMPORTANT = 5
case VERY_IMPORTANT = 4
case IMPORTANT = 3
case NORMAL = 2
case NOT_IMPORTANT = 1
case JUST_FOR_RECORD = 0
case ERROR = -1
}

let english_extremely_important = "Extremely Important"
let english_very_important = "Very Important"
let english_important = "Important"
let english_normal = "Normal"
let english_not_important = "Not Important"
let english_just_for_record = "Just for Record"

var importanceEnglishItems: [String] = {
return [
    english_extremely_important,
    english_very_important,
    english_important,
    english_normal,
    english_not_important,
    english_just_for_record
]
}()

func getImportance(importanceEnglish: String) -> Int8 {
switch importanceEnglish {
case english_extremely_important:
    return Importance.EXTREMELY_IMPORTANT.rawValue
case english_very_important:
    return Importance.VERY_IMPORTANT.rawValue
case english_important:
    return Importance.IMPORTANT.rawValue
case english_normal:
    return Importance.NORMAL.rawValue
case english_not_important:
    return Importance.NOT_IMPORTANT.rawValue
case english_just_for_record:
    return Importance.JUST_FOR_RECORD.rawValue
default:
    return Importance.ERROR.rawValue
}

}

Всякий раз, когда пользователь выбирает элемент во всплывающем меню, этот код выполняет:

    @IBAction func handleImportancePopUpButtonSelectionChanged(_ importancePopUpButton: NSPopUpButton) {
    let importanceIndex = getImportance(importanceEnglish: importancePopUpButton.titleOfSelectedItem!)
    print("importanceIndex: \(importanceIndex)")
}

Это работает, НО ... Я считаю, что эта реализацияне так уж и элегантноКакой лучший способ сделать это?

Я имею в виду следующие требования:

  • Соответствующие значения списка перечислений enum Importance: Int8 являются фиксированными.Например, EXTREMELY_IMPORTANT должен быть 5, так как он уже закодирован на стороне сервера.Следовательно, на основе выбора пользователя соответствующие значения перечисления должны быть отправлены на сервер.(EXTREMELY_IMPORTANT == 5 и т. Д.)

  • В дополнение к вышеупомянутому пункту индекс выбора NSPopUpButton не может использоваться для отправки на сервер.Например, «Чрезвычайно важно» будет 0, поскольку оно является первым в верхней части списка.

  • NSPopUpButton использует «titleOfSelectedItem», а затем вызывает getImportance (ImportantEnglish: String) метод, который неэффективен, и вместо него лучше использовать indexOfSelectedItem.Это означает, что было бы более эффективно использовать индекс выбора «Чрезвычайно важный» (равный 0) для получения значения 5 для отправки на сервер.

  • Еще лучше,если все может поддерживать локализацию поддержки (больше языков: японский и т. д.), используя стандартную практику.

Как я могу сделать свой код Swift красивее?

Ответы [ 2 ]

0 голосов
/ 04 февраля 2019

Вы можете создать NSMenuItem с заголовком и важностью в качестве тега и добавить его NSPopUpButton.menu.items.

override func viewDidLoad() {
    super.viewDidLoad()

    popUpButton.menu?.items = self.importanceEnglishItems
}

class func MenuItem(title: String, tag: Int) -> NSMenuItem {
    let item = NSMenuItem(title: title, action: nil, keyEquivalent: "")
    item.tag = tag
    return item
}

var importanceEnglishItems: [NSMenuItem] = {
    return [
        MenuItem(title: "Extremely Important", tag: 5),
        MenuItem(title: "Very Important", tag: 4),
        MenuItem(title: "Important", tag: 3),
        MenuItem(title: "Normal", tag: 2),
        MenuItem(title: "Not Important", tag: 1),
        MenuItem(title: "Just for Record", tag: 0)
    ]
}()

@IBAction func handleSelection(_ sender: NSPopUpButton) {
    guard let item = sender.selectedItem else { return }
    print("importanceIndex: \(item.tag)")
}
0 голосов
/ 04 февраля 2019

Я бы немного изменил инкапсуляцию, чтобы сделать ее более читаемой;На мой взгляд, такое решение было бы лучшим способом начать с (например, добавить локализацию или расширить ее новыми значениями и т. д.) .

. Эта идея, очевидно, не единственнаяКстати, есть много других изменений / решений, которые могут быть такими же хорошими (или, может быть, даже лучше).


Swift 4.2

enum Importance: Int, CaseIterable {

    case extremelyImportant = 5
    case veryImportant = 4
    case important = 3
    case normal = 2
    case notImportant = 1
    case justForRecord = 0

    var friendlyName: String? {

        switch self {
        case .extremelyImportant: return "Extremely Important"
        case .veryImportant: return "Very Important"
        case .important: return "Important"
        case .notImportant: return "Not Important"
        case .justForRecord: return "Just for Record"
        default: return nil
        }
    }

    init?(withName name: String) {

        guard let importance = Importance.allCases.first(where: {

            guard let friendlyName = $0.friendlyName else { return false }
            return friendlyName == name
        }) else { return nil }

        self = importance
    }

    static var allCasesNames: [String] {

        return Importance.allCases.compactMap { $0.friendlyName }
    }
}
...