【问题标题】:Transparent and Blurred fullScreenCover modal in SwiftUI?SwiftUI 中的透明和模糊 fullScreenCover 模态?
【发布时间】:2021-01-29 15:17:59
【问题描述】:

我是在我的 SwiftUI 项目中显示模式的 fullScreenCover。

但是,我需要以透明和模糊的背景显示模态框。

但我似乎根本无法做到这一点。

这是我的代码:

.fullScreenCover(isPresented: $isPresented) {
                       VStack(spacing: 20) {
                           Spacer()
                               .frame(maxWidth: .infinity, minHeight: 100)
                               .background(Color.black)
                               .opacity(0.3)
                           
                           //Text("modal")
                       }
                       .background(SecondView())     // << helper !!
                   }

我在同一个视图上有这个:

struct BackgroundBlurView: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let view = UIVisualEffectView(effect: UIBlurEffect(style: .light))
        DispatchQueue.main.async {
            view.superview?.superview?.backgroundColor = .clear
        }
        return view
    }

    func updateUIView(_ uiView: UIView, context: Context) {}
}

上面的代码将打开全屏模式,但它根本不透明或模糊。

这是我得到的:

我还有什么需要做的吗?

我从哪里获得上述代码的参考:

SwiftUI: Translucent background for fullScreenCover

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    我删除了一些无关的东西,并确保背景中有你可以看到的内容。

    如果没有其他答案中建议的alpha,效果会非常微妙,但确实存在。

    struct ContentView : View {
        @State var isPresented = false
        
        var body: some View {
            VStack {
                Text("Some text")
                Spacer()
                Text("More")
                Spacer()
                Button(action: {
                    isPresented.toggle()
                }) {
                    Text("Show fullscreenview")
                }
                .fullScreenCover(isPresented: $isPresented) {
                    Text("modal")
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                    .background(BackgroundBlurView())
                }
                Spacer()
                Text("More text")
            }
            
        }
    }
    
    struct BackgroundBlurView: UIViewRepresentable {
        func makeUIView(context: Context) -> UIView {
            let view = UIVisualEffectView(effect: UIBlurEffect(style: .light))
            DispatchQueue.main.async {
                view.superview?.superview?.backgroundColor = .clear
            }
            return view
        }
    
        func updateUIView(_ uiView: UIView, context: Context) {}
    }
    
    

    注意你可以从Button 中看到的非常微妙的蓝色。在深色模式下更明显。

    当您向背景视图添加更多颜色和内容时,效果可能会变得更加生动。不过,添加alpha 肯定会让事情变得更加明显。

    【讨论】:

      【解决方案2】:

      @Asperi 回答 from here 是完全正确的。只需要添加 alpha 来模糊视图。

      struct BackgroundBlurView: UIViewRepresentable {
          func makeUIView(context: Context) -> UIView {
              let view = UIVisualEffectView(effect: UIBlurEffect(style: .light))
              view.alpha = 0.5 //< --- here
              DispatchQueue.main.async {
                  view.superview?.superview?.backgroundColor = .clear
              }
              return view
          }
          
          func updateUIView(_ uiView: UIView, context: Context) {}
      }
      

      另一种方法是使用 ViewControllerHolder reference link

      struct ViewControllerHolder {
          weak var value: UIViewController?
      }
      
      struct ViewControllerKey: EnvironmentKey {
          static var defaultValue: ViewControllerHolder {
              return ViewControllerHolder(value: UIApplication.shared.windows.first?.rootViewController)
          }
      }
      
      extension EnvironmentValues {
          var viewController: UIViewController? {
              get { return self[ViewControllerKey.self].value }
              set { self[ViewControllerKey.self].value = newValue }
          }
      }
      
      extension UIViewController {
          func present<Content: View>(backgroundColor: UIColor = UIColor.clear, @ViewBuilder builder: () -> Content) {
              let toPresent = UIHostingController(rootView: AnyView(EmptyView()))
              toPresent.view.backgroundColor = backgroundColor
              toPresent.modalPresentationStyle = .overCurrentContext
              toPresent.modalTransitionStyle = .coverVertical
              toPresent.rootView = AnyView(
                  builder()
                      .environment(\.viewController, toPresent)
              )
              
              //Add blur efect
              let blurEfect = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
              blurEfect.frame = UIScreen.main.bounds
              blurEfect.alpha = 0.5
              toPresent.view.insertSubview(blurEfect, at: 0)
              self.present(toPresent, animated: true, completion: nil)
          }
      }
      
      struct ContentViewNeo: View {
          @Environment(\.viewController) private var viewControllerHolder: UIViewController?
          
          var body: some View {
              VStack {
                  Text("Background screen")
                  Button("Open") {
                      viewControllerHolder?.present(builder: {
                          SheetView()
                      })
                  }
              }
          }
      }
      
      struct SheetView: View {
          var body: some View {
              Text("Sheet view")
                  .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-28
        • 2010-09-30
        • 1970-01-01
        • 2013-01-24
        • 2015-11-05
        • 2021-06-24
        • 2016-11-18
        • 2015-03-18
        相关资源
        最近更新 更多