У меня есть UIViewController с несколькими UIViews с именами view0, view1, view2... После очереди синтаксического анализа мое приложение получает parsedArray и должно изменить цвет фона отдельных представлений в зависимости от его значения. Чтобы избежать длинных подпрограмм if...else, я хочу использовать оператор switch...case: так, как лучше всего управлять этими несколькими именами UIView? strong> в оператор switch...case? Расширение? Я знаю, что мог бы использовать представления Collection или UIStackViews, но у меня уже есть много методов, ориентированных на отдельные UIViews, и, кстати, я хотел бы узнать, как лучше всего управлять несколькими именами в имени типа, таком как UIView. Спасибо!

    func colorViews() {
    
    for i in 0...21
    {
        switch (parsedArray[i]) {
        case "0": viewX.backgroundColor = .systemRed // HERE X MUST BE i
        default:
             viewX.backgroundColor = .systemGreen // HERE X MUST BE i
        }

    }
    

enter image description here

0
Huxley 14 Янв 2022 в 13:44
1
Может быть, сохранить свои взгляды в массиве?
 – 
Joakim Danielson
14 Янв 2022 в 14:28
Невероятно, мне нужно только объявить простой массив имен. Спасибо!
 – 
Huxley
14 Янв 2022 в 17:56

3 ответа

Лучший ответ

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

В области контроллера:

var views = [UIView]()

В функции viewDidLoad():

views = [view0, view1, view2, view3, view4, view5, view6, view7, view8, view9, view10, view0b, view1b, view2b, view3b, view4b, view5b, view6b, view7b, view8b, view9b, view10b]

В операторе switch...case:

        for i in 0...21
    {
        switch (parsedArray[i]) {
        case "0":
            views[i].backgroundColor = .systemRed // HERE [i] CALLS SINGLE UIVIEW NAME!
        case "1":
            views[i].backgroundColor = .systemGreen // HERE [i] CALLS SINGLE UIVIEW NAME!
        default:
            print("DEFAULT!")
        }
    }
0
Huxley 14 Янв 2022 в 17:54

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

Это образец:

extension UIView {

    var id: String? {
        get {
            return self.accessibilityIdentifier
        }
        set {
            self.accessibilityIdentifier = newValue
        }
    }

    func view(withId id: String) -> UIView? {
        if self.id == id {
            return self
        }
        for view in self.subviews {
            if let view = view.view(withId: id) {
                return view
            }
        }
        return nil
    }
}

После этого вы можете получить доступ к своим представлениям, например:

let view = UIView.view(withId: 0)
1
wazowski 14 Янв 2022 в 14:47
Очень интересное предложение, я его изучу, но то, что предложил комментарий Йоакима, самое простое! Спасибо!
 – 
Huxley
14 Янв 2022 в 17:56

Либо поместите свои представления в массив, либо создайте функцию, которая возвращает вам представление для данного индекса.

Массивный подход выглядит следующим образом:

private var nodeViews: [UIView] {
    return [
        view0, view1, view2, view3, view4, view5,
        view6, view7, view8, view9, view10, view11,

        view12, view13, view14, view15, view16, view17,
        view18, view19, view20, view21, view22, view23
    ]
}

И у вас будет такой метод, как

private func refreshNodeColors() {
    let nodes = self.nodeViews
    parsedArray.enumerated().forEach { index, value in
        guard index < nodes.count else { return } // More data in array than nodes supported
        nodes[index].backgroundColor = {
            switch value {
                case "0": return .systemRed
                default: return .systemGreen
            }
        }()
    }  
}

Функция, которая возвращает представление с индексом, будет выглядеть так

private func nodeWithIndex(_ index: Int) -> UIView? {
    switch index {
        case 0: return view0
        case 1: return view1
        // TODO: add other views here as well
        default: return nil
    }
}

И вы бы использовали его так

private func refreshNodeColors() {
    parsedArray.enumerated().forEach { index, value in
        guard let node = nodeWithIndex(index) else { return } // Node with this index does not exist
        node.backgroundColor = {
            switch value {
                case "0": return .systemRed
                default: return .systemGreen
            }
        }()
    }  
}
1
Matic Oblak 14 Янв 2022 в 16:11
Тоже очень интересное предложение, я его изучу, но то, что предложил комментарий Йоакима, самое простое! Спасибо!
 – 
Huxley
14 Янв 2022 в 17:56