如何在SwiftUI中制作具有透明背景的模态视图?

20

我从之前的评论中得到了更正,所以我已经将其删除(并将点赞您的问题)。现在看起来您可以通过在ZStack内使用Rectangle来为模态视图提供背景。但是...模态视图的默认设置似乎基于浅色/深色模式设置。如果您使该矩形填充为Color.clear,则仍将有一个覆盖底层视图的背景... - user7014451
希望未来的SwiftUI版本能够拥有您需要的功能,但我认为最好的选择是不使用模态框,而是创建一个全屏视图,并将其设置为透明背景并附加到屏幕上,并提供一种关闭它的方法。由于透明模态框不会显示其边缘,因此您实际上将伪造一个模态框。 - user7014451
mmh可能是一个解决方案,类似于这样(只是在ZStack内出现的视图)https://github.com/peppesapienza/random-code/blob/master/transparent-modal-swiftUI.swift? - Giuseppe Sapienza
6个回答

13

我正在使用协调者模式,在组装中创建视图。

let view = UIHostingController(rootView: swiftuiview)
view.view.backgroundColor = .clear

在路由器内只需呈现此UIHostingController

module.modalPresentationStyle = .overCurrentContext
navigationController.present(module, animated: animated, completion: nil)

不幸的是,看起来UIHostingController的backgroundColor中不包含.clear。 - Legolas Wang
找到了一种使视图透明的方法,即将view.view.background设置为nil而不是.clear,然后您只需要在托管控制器级别或SwftUI视图本身上设置不透明度为零。 - Ash-Bash32

5
如果您想在一个SwiftUI和UIKit混合的项目中对背景进行模糊处理,并且可能使用SwiftUI视图作为模态视图,那么我最近遇到了同样的问题,并创建了一个UIViewController,它接纳了UIHostController(基本上是UIViewController), 然后修改HostingController View的alpha值,在后面放上模糊效果,并将其呈现给父视图。
我已经创建了一个包含该文件的gist以供公开使用。 https://gist.github.com/Ash-Bash/93fd55d89c1e36f592d3868f6b29b259 以下是工作示例:
// Initialises BlurredHostingController
var blurredHostingController = BlurredHostingController()

// Sets the Hosting View for the SwiftUI View Logic
blurredHostingController.hostingController = UIHostingController(rootView: ContentView())

// Blur Tweaks for blurredHostingController
blurredHostingController.blurEffect = .systemMaterial
blurredHostingController.translucentEffect = .ultrathin

// Presents View Controller as a Modal View Controller
self.present(blurredHostingController animated: true, completion: nil)

这是来自macCatalyst的结果:在此输入图片描述

4

现状:

let rootView = Text("Hello world")
let controller = UIHostingController(rootView: rootView)
controller.view.backgroundColor = .clear
UIApplication.shared.windows.first?.rootViewController?.present(controller, animated: true)

忽略:

UIApplication.shared.windows.first?.rootViewController?.dismiss(animated: true)

3

我没有找到理想的方法,但我有一个解决方法。

因此,为了以模态方式呈现视图,您可以使用ZStack并将多个视图分组在其中,并使用@State变量进行处理,如下所示。

这里我给视图设置了背景颜色,以便更好地解释。

struct ContentView : View {
   @State private var showModally = false
   var body : some View {
    ZStack {
        Color.red
        VStack {
            Button(action: {
                withAnimation{
                    self.showModally = true
                }
            }) {
                Text("Push Modally")
            }
        }
        
        ModalView(show: $showModally)
            .offset(y: self.showModally ? 0 : UIScreen.main.bounds.height)
            .animation(.spring())
        
    }
  }
}

struct ModalView: View {
  @Binding var show : Bool
  var body: some View {
    VStack {
        Spacer()
        
        VStack {
            Color.white
        }
        .frame(height : 400)
        .cornerRadius(10)
        .padding(.horizontal)
    }
    .background(Color.clear)
    .onTapGesture {
        self.show = false
    }
  }
}

在此情况下,模态视图将以模态方式呈现在内容视图上方,并通过轻触来关闭。


如何修改代码以覆盖 UITabBar? - Luke Irvin
将TabView包含在ZStack中,其余内容保持不变。类似这样:- ZStack { TabView { Content } ModalView } - Anshuman Singh

2

iOS 16.4+

您可以使用新的修饰符来显示具有透明背景的全屏模态:

presentationBackground(_:)

使用形状样式设置封闭表单的演示背景。

以下是一个例子:

struct ContentView: View {
    @State private var showSettings = false

    var body: some View {
        Button("View Settings") {
            showSettings = true
        }
        .fullScreenCover(isPresented: $showSettings) {
            SettingsView()
                .presentationBackground(.thickMaterial) // <-- this 
        }
    }
}

0
将此代码添加到父视图上,将modalPresentationStyle设置为.formSheet,并通过将preferredContentSize分配给hostingVC来设置大小。
  if segue.identifier == "AnotherView", let hostingController = segue.destination as? HostingSwiftUIView {
    hostingController.modalPresentationStyle = .formSheet
    hostingController.preferredContentSize = CGSize(width: 700, height: 300) // customise as per View
    hostingController.rootView = AnyView(AnotherView())
}

这是以模态方式呈现的子视图。
struct AnotherView : View {
    var body: some View {
        Text("Second View")
            .bold()
            .font(.largeTitle)
    }
}

它会看起来像这样: 在这里输入图像描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接