首页 > 解决方案 > SwiftUI 将覆盖内容传递给父视图

问题描述

MainViewAnotherMainView包含名称数组。它们遍历这些数组并且都使用DetailView来显示带有一些附加内容的名称。MyViewModel提供一些功能,例如添加名称等。这些应该从DetailOverlayView使用所选名称的操作触发(请参阅代码注释。

我的问题是,DetailView在“单元格”内开始一个非常小的覆盖结果,DetailView这不是我想要的。这就是为什么我想在父视图上显示它。不幸的是,我不知道如何将 传递DetailOverlayViewMainViewand AnotherMainView。我尝试使用绑定或环境,但这不起作用。我想避免冗余,例如在两个父视图中定义叠加层等。

或者,也许有一个解决方案可以从 DetailView 调用它,但绕过详细视图框架而不提供一些硬编码的高度和宽度值。

struct MainView: View {
    @StateObject var viewModel: MyViewModel
    var names = ["aaa", "ccc", "ddd", "gght"]
    var body: some View {
        VStack {
            ForEach(names, id: \.self, content: { name in
                DetailView(name: name).environmentObject(viewModel)
            })
        }///.overlay(... ->  need DetailOverlayView here
    }
}

struct AnotherMainView: View {
    @StateObject var viewModel: MyViewModel
    var names = ["bbb", "hhh"]
    var body: some View {
        VStack {
            ForEach(names, id: \.self, content: { name in
                DetailView(name: name).environmentObject(viewModel)
            })
        }///.overlay(... ->  need DetailOverlayView here
    }
}

struct DetailView: View {
    @EnvironmentObject var viewModel: MyViewModel
    @State var name: String
    
    var body: some View {
        VStack {
            Text("Name of the user: ")
            Text(name)
        }///.overlay(... ->  this would show an DetailOverlayView as a part of this small DetailView and in its bounds which is not what I want
    }
    
    struct DetailOverlayView: View {
        @Binding var name: String ///this is the same name that the DetailView has, not sure if binding makes sense here
        @EnvironmentObject var viewModel: MyViewModel
        
        var body: some View {
            VStack {
                Button(action: {
                    viewModel.addName(name: name)
                }, label: {
                    Text("Add name")
                })
                Button(action: {
                    viewModel.doSomething1(name: name)
                }, label: {
                    Text("doSomething1")
                })
                Button(action: {
                    viewModel.doSomething2(name: name)
                }, label: {
                    Text("doSomething2")
                })
            }
        }
    }
}

class MyViewModel: ObservableObject {
    func addName(name: String) {
        ///
    }
    func doSomething1(name: String) {
        ///
    }
    func doSomething2(name: String) {
        ///
    }
}

标签: swiftswiftui

解决方案


推荐阅读