SwiftUI не правильно оценивает остальное? - PullRequest
1 голос
/ 31 января 2020

Я создаю представление SwiftUI, в котором у меня есть три возможных условия, и я хочу показать различный контент в зависимости от того, какое условие выполнено. Упрощенный пример:

struct ContentView: View {

    @State var condition1 = true
    @State var condition2 = false

    var body: some View {
        VStack {
            if condition1 {
                Text("text1")
            } else if condition2 {
                Text("text2")
            } else {
                Text("text3")
            }
        }.onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
                self.condition2 = true
            }

            DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) {
                self.condition1 = false
            }

            DispatchQueue.main.asyncAfter(deadline: .now() + 6.0) {
                self.condition2 = false
            }
        }
    }
}

То, что я ожидаю, произойдет:
1) Пользовательский интерфейс показывает text1 при запуске приложения
2) Пользовательский интерфейс все еще показывает text1 через 2 секунды ( обе переменные true)
3) Пользовательский интерфейс показывает text2 через 4 секунды (condition2 равен true, но condition1 теперь false)
4) Пользовательский интерфейс показывает text3 через 6 секунд (обе переменные теперь false)

Что на самом деле происходит:
1) Пользовательский интерфейс показывает text1 при запуске приложения
2) Пользовательский интерфейс показывает text1 после 2 секунд
3) Пользовательский интерфейс показывает text2 через 4 секунды
4) Пользовательский интерфейс продолжает отображать text2 через 6 секунд

Достаточно странно, если я ставлю точки останова в коде пользовательского интерфейса строка text3 выполняется, просто кажется, что пользовательский интерфейс никогда не обновляется. Еще более странно, если я добавлю Spacer().frame(width: 0, height: 0) в другом случае, все будет работать как положено.

Это ошибка в SwiftUI или что здесь происходит?

1 Ответ

1 голос
/ 31 января 2020

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

Вот собственно решение , который работает (протестировано с Xcode 11.2 / iOS 13.2) ... разделяет эти условно зависимые представления на специализированный построитель представлений, как показано ниже

struct TestRefreshOnCondition: View {
    @State var condition1 = true
    @State var condition2 = false

    var ConditionalView: some View {
        Group {
            if condition1 {
                Text("text1")
            } else if condition2 {
                Text("text2")
            } else {
                Text("text3")
            }
        }
    }

    var body: some View {
        VStack {
            ConditionalView
        }.onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
                self.condition2 = true
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 4.0) {
                self.condition1 = false
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 6.0) {
                self.condition2 = false
            }
        }
    }
}
...