SwiftUI 中的透明和模糊 fullScreenCover 模态?
Posted
技术标签:
【中文标题】SwiftUI 中的透明和模糊 fullScreenCover 模态?【英文标题】:Transparent and Blurred fullScreenCover modal in SwiftUI? 【发布时间】: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
【问题讨论】:
【参考方案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)
【讨论】:
以上是关于SwiftUI 中的透明和模糊 fullScreenCover 模态?的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI:函数声明了一个不透明的返回类型,但其主体中的返回语句没有匹配的底层类型