问题
I want to create such view hierarchy
ZStack {
TabView {
NavigationView {
NavigationLink ... {
Subview()
}
}
}
FullScreenView()
}
inside subview there is button which toogles environment variable to present full screen view like in this example: https://github.com/nikishovde/HideTabBarInSubview how to inject subview contents to full screen view when showFullscreen variable is toggled true ? ( I want to make FullScreenView generic so I can use it for different views which I want to present on full screen)
edited: added code
struct FullScreen: View {
@EnvironmentObject var userData: UserData
var body: some View {
VStack {
Text("INSERT SlidesView() here ...")
}
.frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
.background(Color.red)
}
}
struct SlidesView: View {
@EnvironmentObject var userData: UserData
var slidesURL: String
var body: some View {
ZStack(alignment: .topTrailing) {
Webview(url: slidesURL).padding(5)
Button(action: {
self.userData.showFullScreen.toggle()
}) {
Image(systemName: "arrow.up.left.and.arrow.down.right")
.padding(10)
.background(Color.white)
.clipShape(RoundedRectangle(cornerRadius: 10))
.offset(x: 10, y: 10)
.padding(10)
.foregroundColor(.blue)
}
.navigationBarTitle("test")
}
}
}
struct AppView: View {
@EnvironmentObject var userData: UserData
@ObservedObject var auth = Auth.shared
var body: some View {
ZStack {
Group {
if self.auth.authToken != nil && !self.firstLaunch {
TabView {
ViewWithNavigationView().environmentObject(self.userData)
.tabItem {
Image(systemName: "tv")
Text(verbatim: "Talks")
}.tag(0)
}
} else {
// TODO: 2020-03-06 - Create better onboarding screen
VStack(spacing: 20) {
Text("Hello!").font(.largeTitle)
Text("I prepare Code Conf App for your first use.")
// FIXME: 2020-03-06 - Disable button after first tap and add spinner as loading indicator
Button(action: {
self.firstLaunch.toggle()
UserDefaultsConfig.firstLaunch = self.firstLaunch
}) {
Text("OK")
}
}
}
if self.userData.showFullScreen {
FullScreen().environmentObject(self.userData)
}
}
}
}
}
final class UserData: ObservableObject {
@Published var showFullScreen = false
}
回答1:
Here is a demo of possible approach (used simplified part of your code as not all dependencies provided). Tested with Xcode 11.4 / iOS 13.4
class FullScreenData: ObservableObject {
@Published var originalView: (() -> AnyView)? = nil
}
struct FullScreenView: View {
@EnvironmentObject var fullScreenData: FullScreenData
var body: some View {
Group {
if fullScreenData.originalView != nil {
fullScreenData.originalView!()
.edgesIgnoringSafeArea(.all)
} else {
EmptyView()
}
}
}
}
struct SlidesView: View {
@EnvironmentObject var fullScreenData: FullScreenData
var body: some View {
ZStack(alignment: .topTrailing) {
Rectangle() // demo placeholder
.fill(Color.yellow).border(Color.red)
Button(action: {
self.fullScreenData.originalView =
self.fullScreenData.originalView == nil ? { AnyView(self) } : nil
}) {
Image(systemName: "arrow.up.left.and.arrow.down.right")
.padding(10)
.background(Color.white)
.clipShape(RoundedRectangle(cornerRadius: 10))
.offset(x: 10, y: 10)
.padding(10)
.foregroundColor(.blue)
}
.navigationBarTitle("test")
}
}
}
struct TestFullScreen: View {
@EnvironmentObject var fullScreenData: FullScreenData
var body: some View {
ZStack {
TabView {
NavigationView {
NavigationLink(destination: Text("Destination")) {
SlidesView()
}
}.tabItem {
Image(systemName: "1.circle")
}
}
FullScreenView()
}
}
}
struct TestFullScreen_Previews: PreviewProvider {
static var previews: some View {
TestFullScreen().environmentObject(FullScreenData())
}
}
来源:https://stackoverflow.com/questions/61518368/swiftui-view-injection-into-other-view