SwiftUI .onAppear 和 ViewModifier (Progress) 过程。为什么它很重要?

问题描述 投票:0回答:1

我制作了一个自定义 ViewModifier,例如“进度栏”(但在下面的代码中,例如,我仅使用不同的背景颜色。

我有一个从 API 下载数据的功能(例如,在下面的代码中,我使用延迟 3 秒的“假”下载。

我使用布尔变量来检查是否正在加载。

我的问题是,为什么我要写

.进展 .onAppear {下载函数}

一切都好,但如果我改变顺序

.onAppear {下载函数} .进度

这将是无尽的“进步”,我的主视图将永远不会显示。

我需要理解为什么会发生这种情况,以及为什么其他顺序一切都好。

struct ContentView: View {
    
    @State private var isLoaded = true
    
    var body: some View {
        ZStack {
            Color.blue
                .ignoresSafeArea()
            Text("Example")
                .foregroundStyle(.white)
                .font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/)
                .bold()
        }
        .onAppear { fakeNetworkCall() }
        .progress(isLoaded: isLoaded)
    }

    
    func fakeNetworkCall() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 3 ) {
            isLoaded = false
        }
    }
}


struct LoadingView: ViewModifier {
    var isLoaded : Bool
    func body(content: Content) -> some View {
        if isLoaded {
            ZStack {
                Color.red
                    .ignoresSafeArea()
                Text("Example")
                    .foregroundStyle(.white)
                    .font(/*@START_MENU_TOKEN@*/.title/*@END_MENU_TOKEN@*/)
                    .bold()
            }
        } else {
          content
        }
    }
}


extension View {
    func progress(isLoaded: Bool) -> some View {
        modifier(LoadingView(isLoaded: isLoaded))
    }
}

当我悲伤时,如果我会改变

        .progress(isLoaded: isLoaded)
        .onAppear { fakeNetworkCall() }

一切都好,但我不明白为什么。

ios swift swiftui viewmodifier
1个回答
0
投票

想象一下“内联”视图修饰符,它会变得非常清晰。换句话说,将视图修改器的

content
中的
body
替换为它正在修改的实际视图:

if isLoaded {
    ZStack {
        Color.red
            .ignoresSafeArea()
        Text("Example")
            .foregroundStyle(.white)
            .font(.title)
            .bold()
    }
} else {
    ZStack {
        Color.blue
            .ignoresSafeArea()
        Text("Example")
            .foregroundStyle(.white)
            .font(.title)
            .bold()
    }
    .onAppear { fakeNetworkCall() }
}

onAppear
修饰符修改
ZStack
分支中的
else
。由于
if
语句最初为 true,因此
else
中的视图永远不会出现,因此
onAppear
永远不会被调用。

如果将

progress
放在
onAppear
之前,
onAppear
会修改整个
if...else
语句(又名
_ConditionalContent
),即视图修改器的主体。这个视图总是出现。

有点像这样

Group {
    if isLoaded {
        ZStack {
            Color.red
                .ignoresSafeArea()
            Text("Example")
                .foregroundStyle(.white)
                .font(.title)
                .bold()
        }
    } else {
        ZStack {
            Color.blue
                .ignoresSafeArea()
            Text("Example")
                .foregroundStyle(.white)
                .font(.title)
                .bold()
        }
    }
}
.onAppear { fakeNetworkCall() }
© www.soinside.com 2019 - 2024. All rights reserved.