Троичное условие не работает в SwiftUI

#swift #swiftui

#swift #swiftui

Вопрос:

Кто-нибудь знает, поддерживает ли SwiftUI троичные условия? У меня есть текстовое представление с условным аргументом ( Text(badgeCount == nil ? " " :"(badgeCount!)") ), которое отображает пустое представление. Удивительно, но это работает, если я удаляю @State атрибут из представления.

 import SwiftUI

struct RedBadgeView: View {
    @State var badgeCount: Int?
    
    init (_ badgeCount: Int? = nil) {
        self.badgeCount = badgeCount
    }
    
    var body: some View {
        // Something about this Syntax is throwing off SwiftUI. 
        Text(badgeCount == nil ? " " :"(badgeCount!)")
    }
}

struct RedBadgeView_Previews: PreviewProvider {
    static var previews: some View {
        RedBadgeView(1)
    }
}

  

Ответ №1:

Здесь вообще нет необходимости использовать троичный оператор. Более того, выполнение нулевой проверки, а затем принудительное разворачивание в троичном операторе — плохая идея.

Вместо этого вы должны использовать необязательную цепочку для доступа к description of badgeCount и указать значение " " по умолчанию.

 Text(badgeCount?.description ?? " ")
  

Однако ваша проблема с тем, что представление не обновляется, связана с тем фактом, что вы никогда не инициализируете свое State , вы просто присваиваете значение его обернутому значению. Чтобы получить доступ к состоянию, вам нужно использовать _ префикс перед именем переменной.

 init (_ badgeCount: Int? = nil) {
    self._badgeCount = State(initialValue: badgeCount)
}
  

Ответ №2:

Конечно, троичные условия работают. Однако ваша инициализация состояния неверна. Вы инициализируете обычный Int.

 init (_ badgeCount: Int? = nil) {
    self.badgeCount = badgeCount // >> If you initializing an Int
    self._badgeCount = State(initialValue: badgeCount) // >> If you initializing a State variable
}
  

Следовательно, все будет работать и с состоянием:

 struct ContentView: View {
    @State var badgeCount: Int?
    
    init (_ badgeCount: Int? = nil) {
        self._badgeCount = State(initialValue: badgeCount)
    }
    
    var body: some View {
        Text(badgeCount == nil ? " " :"(badgeCount!)")
    }
}
  

Ответ №3:

В дополнение к другим ответам, если вы используете SwiftUI 2, вы можете сделать это более быстрым способом, который заключается в использовании if-let непосредственно в body :

 var body: some View {
    if let badgeCount = badgeCount {
        Text(badgeCount)
    }
}
  

Если badgeCount есть nil , body то вернет an EmptyView . Однако вы можете вернуть и какой-нибудь другой вид:

 @ViewBuilder
var body: some View {
    if let badgeCount = badgeCount {
        Text(badgeCount)
    } else {
        Text(" ")
    }
}
  

(Сначала вам нужно инициализировать / присвоить значение badgeCount , чтобы увидеть представление).