SwiftUI 视图注入其他视图 [英] SwiftUI view injection into other view

查看:22
本文介绍了SwiftUI 视图注入其他视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建这样的视图层次

ZStack {标签视图{导航视图{导航链接 ... {子视图()}}}全屏视图()}

在子视图中有一个按钮,它可以通过环境变量来显示全屏视图,如本例所示:

class FullScreenData: ObservableObject {@Published var originalView: (() -> AnyView)?= 零}struct FullScreenView:查看{@EnvironmentObject var fullScreenData: FullScreenDatavar主体:一些视图{团体 {如果 fullScreenData.originalView != nil {fullScreenData.originalView!().edgesIgnoringSafeArea(.all)} 别的 {空视图()}}}}结构幻灯片视图:查看{@EnvironmentObject var fullScreenData: FullScreenDatavar主体:一些视图{ZStack(对齐:.topTrailing){Rectangle()//演示占位符.fill(Color.yellow).border(Color.red)按钮(动作:{self.fullScreenData.originalView =self.fullScreenData.originalView == nil ?{ AnyView(self) } : 无}) {图像(系统名称:arrow.up.left.and.arrow.down.right").填充(10).background(颜色.白色).clipShape(RoundedRectangle(cornerRadius: 10)).offset(x: 10, y: 10).填充(10).foregroundColor(.blue)}.navigationBarTitle("测试")}}}struct TestFullScreen:查看{@EnvironmentObject var fullScreenData: FullScreenDatavar主体:一些视图{ZStack {标签视图{导航视图{NavigationLink(目的地:文本(目的地")){幻灯片视图()}}.tabItem {图像(系统名称:1.circle")}}全屏视图()}}}struct TestFullScreen_Previews: PreviewProvider {静态 var 预览:一些视图 {TestFullScreen().environmentObject(FullScreenData())}}

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
}

解决方案

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())
    }
}

这篇关于SwiftUI 视图注入其他视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆