温馨提示:本文翻译自stackoverflow.com,查看原文请点击:ios - SwiftUI does not evaluate elseif correctly?
ios swiftui swiftui-bug

ios - SwiftUI无法正确评估elseif?

发布于 2020-03-31 23:46:56

我正在创建一个具有三个可能条件的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)的UI显示text1,当应用程序开始
2)用户界面仍然显示text12秒后(两个变量都是true
3)UI显示text24秒后(condition2true,但condition1现在是false
4)用户界面会显示text36后秒(两个变量都现在false

实际发生的情况:
1)UI text1在应用程序启动时显示
2)UI text1在2秒后显示
3)UI text2在4秒后显示
4)UI text2在6秒后继续显示

足够奇怪的是,如果我在UI代码中放置断点,则执行了显示text3的行,似乎UI从未更新。更奇怪的是,如果我Spacer().frame(width: 0, height: 0)在其他情况下放一个,一切都会按预期进行。

这是SwiftUI中的错误还是在这里发生了什么?

查看更多

提问者
BlackWolf
被浏览
84
Asperi 2020-01-31 20:04

好吧,实际上,如果要添加按钮并在按钮上切换状态,那么所有方法都可以正常工作,所以这是延迟更新的内容(可能是赛车,可能是错误……没有进一步研究)

这实际上是可行的解决方案(已通过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
            }
        }
    }
}