简体   繁体   English

使用@State 变量不适用于从子视图更改 Body 中的视图 state

[英]Using @State variable does not work for changing view state in Body from child view

Let's say in my iOS SwiftUI app there is a simple ContentView with two views inside.假设在我的 iOS SwiftUI 应用程序中有一个简单的 ContentView,里面有两个视图。

The reference to ContentView is available to other parts of code.对 ContentView 的引用可用于代码的其他部分。

From there the user wants to determine which of the two views are displayed, that is, one, none or both.用户想要从那里确定显示两个视图中的哪一个,即一个、一个、一个或两个。

That code is something like该代码类似于

contentViewReference.setView1Visible(view1Visible:true) //or false

Here's the ContentView这是内容视图

struct ViewsState
{
    var view1Visible:Bool
    var view2Visible:Bool
    init(view1Visible:Bool,view2Visible:Bool)
       {
          self.view1Visible=view1Visible
          self.view2Visible=view2Visible
       }
 }

struct ContentView: View 
{ 
    @State private var viewsState:ViewsState=ViewsState(view1Visible:true,view2Visible:false)

    
    public func setView1Visible(view1Visible:Bool)
        {
          viewsState.view1Visible=view1Visible
        }

    public func setView2Visible(view2Visible:Bool)
        {
          viewsState.view2Visible=view2Visible
        }

    var body: some View 
    {
        if (viewsState.view1Visible) {View1}
        if (viewsState.view1Visible) {View2}
    }
}

but the views' visibility does never change, why?但是视图的可见性永远不会改变,为什么?

I do not think I need Binding because the state "truth" is inside ContentView, but it is assigned through public funcs.我认为我不需要绑定,因为 state“真相”在 ContentView 内部,但它是通过公共功能分配的。

There is no parent View, the toggling code indeed is inside a menu that is part of View1.没有父视图,切换代码确实位于属于 View1 的菜单内。

But when calling但是打电话的时候

setView1Visible(view1Visible:false)

for example, there is no effect, View1 does not become hidden.例如,没有效果,View1 不会隐藏。

This is just a snippet of code.这只是一小段代码。 Real ContentView is slightly more elaborate, but the question does not change.真正的 ContentView 稍微复杂一些,但问题没有改变。

@P5music, there is not enough code to replicate your issue and investigate properly. @P5music,没有足够的代码来复制您的问题并进行适当的调查。 Also I don't know how you get:我也不知道你是怎么得到的:

   contentViewReference.setView1Visible(view1Visible:true) 

Here are some observations regarding your code.以下是关于您的代码的一些观察。

    @State private var viewsState:ViewsState(view1Visible:true,view2Visible:false)

should be应该

    @State var viewsState = ViewsState(view1Visible:true,view2Visible:false)

also you probably want:你也可能想要:

    var body: some View 
{
    if (viewsState.view1Visible) {View1}
    if (viewsState.view2Visible) {View2}  // <--- here 
}

In addition, "...determine which of the two views are displayed", this means that every time you set "view1Visible" to some value, at the same time you also need to set "view2Visible" to the opposite.此外,“...确定显示两个视图中的哪一个”,这意味着每次将“view1Visible”设置为某个值时,同时还需要将“view2Visible”设置为相反的值。

class ViewsState: ObservableObject
{
    @Published var view1Visible:Bool
    @Published var view2Visible:Bool
    init(view1Visible:Bool,view2Visible:Bool)
    {
        self.view1Visible=view1Visible
        self.view2Visible=view2Visible
    }
    public func setView1Visible(view1Visible:Bool)
    {
        self.view1Visible = view1Visible
        view2Visible = !view1Visible
    }
    
    public func setView2Visible(view2Visible:Bool)
    {
        self.view2Visible = view2Visible
        view1Visible = !view2Visible
    }
}

struct ViewStateView: View {
    @StateObject private var viewsState: ViewsState = ViewsState(view1Visible:true,view2Visible:false)

    var body: some View
    {
        VStack{
            if (viewsState.view1Visible) {Text("View1")}
            if (viewsState.view2Visible) {Text("View2")}
            SomeOtherView().environmentObject(viewsState)
        }
    }
}
struct SomeOtherView: View {
    @EnvironmentObject var viewsState: ViewsState
    var body: some View
    {
        VStack{
            Text("SomeOtherView")
            Button("change state view 1", action: {
                viewsState.setView1Visible(view1Visible:false)
            })
            Button("change state view 2", action: {
                viewsState.setView2Visible(view2Visible:false)
            })
        }
        
    }
}
struct ViewStateView_Previews: PreviewProvider {
    static var previews: some View {
        ViewStateView()
    }

Assuming your "contentViewReference.setView1Visible(view1Visible:true)" works, the following test code seems to work:假设您的“contentViewReference.setView1Visible(view1Visible:true)”有效,则以下测试代码似乎有效:

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ViewsState{
    var view1Visible:Bool
    var view2Visible:Bool
    init(view1Visible:Bool, view2Visible:Bool){
        self.view1Visible = view1Visible
        self.view2Visible = view2Visible
    }
}

struct ContentView: View {
    @State var viewsState = ViewsState(view1Visible:true, view2Visible:false)
    
    public func setView1Visible(view1Visible:Bool){
        viewsState.view1Visible = view1Visible
        viewsState.view2Visible = !view1Visible
    }
    
    public func setView2Visible(view2Visible:Bool){
        viewsState.view2Visible = view2Visible
        viewsState.view1Visible = !view2Visible
    }
    
    var body: some View {
        VStack {
            Button("change view") {
                if viewsState.view1Visible {
                    setView1Visible(view1Visible: false)
                } else {
                    setView1Visible(view1Visible: true)
                }
            }
            if (viewsState.view1Visible) {View1()}
            if (viewsState.view2Visible) {View2()}
        }
    }
}

struct View1: View {
    var body: some View {
        Text("View1")
    }
}

struct View2: View {
    var body: some View {
        Text("View2")
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 更改 @State 变量不会更新 SwiftUI 中的视图 - Changing @State variable does not update the View in SwiftUI SwiftUI 更改 State 不会关闭模态视图 - SwiftUI Changing State does not Dismiss Modal View 为什么从视图中触发 function 会更新 @State 变量,但从另一个视图触发相同的 function 不会? - Why is it that triggering a function from within a view updates the @State variable, but triggering that same function from another view does not? 关于将状态从一个视图控制器更改为另一个视图控制器? - About changing state from one view controller to another? SwiftUI:当 state 变量更改时,视图不会更新 - SwiftUI: View does not update when state variable changes UITabBarController 的 iOS 状态恢复不恢复子视图控制器或选定的索引 - iOS State Restoration of UITabBarController Does Not Restore Child View Controllers or Selected Index SwiftUI - 如何在更新父视图的 state 时保留子视图的 state? - SwiftUI - How to preserve child view's state when updating parent view's state? SwiftUI - 使用 ForEach 时,您应该在子视图中使用 `@State var` 还是 `let` - SwiftUI - Should you use `@State var` or `let` in child view when using ForEach 使用segues时保留View Controller的状态 - Preserve state of View Controller when using segues SwiftUI:从 ViewModel 更改视图 @State 属性 - SwiftUI: Change view @State property from ViewModel
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM