swift 如何在工作表视图中使用不透明的背景色?

wsewodh2  于 2024-01-05  发布在  Swift
关注(0)|答案(8)|浏览(205)

我正在使用SwiftUI开发一个应用程序。
我正在寻找一些方法,使一个不透明的工作表视图的背景颜色。
有什么办法吗?
我试着用下面的代码做到这一点,我可以用不透明度属性更改颜色,但我看不到工作表视图下的文本(工作表)。

  1. import SwiftUI
  2. struct ContentView: View {
  3. @State var isSheet = false
  4. var body: some View {
  5. Button(action: {self.isSheet.toggle()}) {
  6. Text("Sheet")
  7. }.sheet(isPresented: $isSheet){
  8. Color.yellow.opacity(0.5)
  9. }
  10. }
  11. }
  12. struct ContentView_Previews: PreviewProvider {
  13. static var previews: some View {
  14. ContentView()
  15. }
  16. }

字符串
Xcode:Version 11.7
Swift:Swift 5

vvppvyoh

vvppvyoh1#

你不能使用标准的工作表官方API(因为默认情况下每个主机控制器视图都是不透明的),所以你可以创建自定义工作表视图(带有你需要的任何功能),或者使用运行时解决方法来找到该视图并将其背景设置为清除。


的数据

  1. struct DemoView: View {
  2. @State var isSheet = false
  3. var body: some View {
  4. Button(action: {self.isSheet.toggle()}) {
  5. Text("Sheet")
  6. }.sheet(isPresented: $isSheet){
  7. Color.yellow.opacity(0.5)
  8. .background(BackgroundClearView())
  9. }
  10. }
  11. }
  12. struct BackgroundClearView: UIViewRepresentable {
  13. func makeUIView(context: Context) -> UIView {
  14. let view = UIView()
  15. DispatchQueue.main.async {
  16. view.superview?.superview?.backgroundColor = .clear
  17. }
  18. return view
  19. }
  20. func updateUIView(_ uiView: UIView, context: Context) {}
  21. }

字符串
backup

展开查看全部
7y4bm7vi

7y4bm7vi2#

使用我一整天都在努力寻找的来自@ marti的令人敬畏的答案,我已经构建了一个简单的视图修改器,现在可以在.sheet或.fullScreenCover模态视图中应用,并提供透明的背景。然后您可以根据需要为内容设置框架修改器,以适应屏幕,而无需用户知道模态不是自定义大小。

  1. import SwiftUI
  2. struct ClearBackgroundView: UIViewRepresentable {
  3. func makeUIView(context: Context) -> some UIView {
  4. let view = UIView()
  5. DispatchQueue.main.async {
  6. view.superview?.superview?.backgroundColor = .clear
  7. }
  8. return view
  9. }
  10. func updateUIView(_ uiView: UIViewType, context: Context) {
  11. }
  12. }
  13. struct ClearBackgroundViewModifier: ViewModifier {
  14. func body(content: Content) -> some View {
  15. content
  16. .background(ClearBackgroundView())
  17. }
  18. }
  19. extension View {
  20. func clearModalBackground()->some View {
  21. self.modifier(ClearBackgroundViewModifier())
  22. }
  23. }

字符串
使用方法:

  1. .sheet(isPresented: $isPresented) {
  2. ContentToDisplay()
  3. .frame(width: 300, height: 400)
  4. .clearModalBackground()
  5. }

展开查看全部
pkbketx9

pkbketx93#

从iOS 16.4开始,应该可以使用带有颜色和模糊的.presentationBackground(_ style: S)material types)。如果你想为一张纸制作透明背景:

  1. struct ContentView: View {
  2. @State private var isPresented = false
  3. var body: some View {
  4. Button(action: {
  5. isPresented.toggle()
  6. }, label: {
  7. Label("Sheet", systemImage: "list.bullet.rectangle.portrait")
  8. })
  9. .sheet(isPresented: $isPresented) {
  10. Text("Detail")
  11. .presentationBackground(.clear)
  12. }
  13. }
  14. }

字符串
或者你可以使用.presentationBackground()来继承presenter的背景样式。

  1. struct ContentView: View {
  2. @State private var isPresented = false
  3. var body: some View {
  4. Button(action: {
  5. isPresented.toggle()
  6. }, label: {
  7. Label("Sheet", systemImage: "list.bullet.rectangle.portrait")
  8. })
  9. .sheet(isPresented: $isPresented) {
  10. Text("Detail")
  11. .presentationBackground()
  12. }
  13. .backgroundStyle(Color("myThemeBackground"))
  14. }
  15. }

展开查看全部
b09cbbtk

b09cbbtk4#

虽然提供的解决方案确实有效,但当它们被交换时,它们也会保持背景对 * 其他 * 工作表透明。
所以需要在dismantleUIView中恢复背景颜色,如下所示:

  1. struct TransparentBackground: UIViewRepresentable {
  2. @MainActor
  3. private static var backgroundColor: UIColor?
  4. func makeUIView(context: Context) -> UIView {
  5. let view = UIView()
  6. Task {
  7. Self.backgroundColor = view.superview?.superview?.backgroundColor
  8. view.superview?.superview?.backgroundColor = .clear
  9. }
  10. return view
  11. }
  12. static func dismantleUIView(_ uiView: UIView, coordinator: ()) {
  13. uiView.superview?.superview?.backgroundColor = Self.backgroundColor
  14. }
  15. func updateUIView(_ uiView: UIView, context: Context) {}
  16. }

字符串
请注意,我使用了Swift中新的并发特性。

展开查看全部
mrzz3bfm

mrzz3bfm5#

对于那些认为依赖于DispatchQueue中的消息顺序不是一个好主意的人(实际上不是),这里有一个依赖于重写didMoveToSuperview()的解决方案。
这仍然不是100%的未来证明,因为我们正在修改superview的superview,并且不能保证它在我们自己的视图添加到层次结构时可用,但我认为这仍然比DispatchQueue解决方案更好,因为视图通常是从上到下添加的,即当调用didMoveToSuperview()时,superview的superview可能可用。

  1. struct DemoView: View {
  2. @State var isSheet = false
  3. var body: some View {
  4. Button(action: {self.isSheet.toggle()}) {
  5. Text("Sheet")
  6. }.sheet(isPresented: $isSheet){
  7. Color.yellow.opacity(0.5)
  8. .background(BackgroundClearView())
  9. }
  10. }
  11. }
  12. struct BackgroundClearView: UIViewRepresentable {
  13. private class View: UIView {
  14. override func didMoveToSuperview() {
  15. super.didMoveToSuperview()
  16. superview?.superview?.backgroundColor = .clear
  17. }
  18. }
  19. func makeUIView(context: Context) -> UIView {
  20. return View()
  21. }
  22. func updateUIView(_ uiView: UIView, context: Context) {}
  23. }

字符串

展开查看全部
scyqe7ek

scyqe7ek6#

把它放在Modal.swift中:

  1. import SwiftUI
  2. // View modifiers for modals: .sheet, .fullScreenCover
  3. struct ModalColorView: UIViewRepresentable {
  4. let color: UIColor
  5. func makeUIView(context: Context) -> some UIView {
  6. let view = UIView()
  7. DispatchQueue.main.async {
  8. view.superview?.superview?.backgroundColor = color
  9. }
  10. return view
  11. }
  12. func updateUIView(_ uiView: UIViewType, context: Context) {}
  13. }
  14. struct ModalColorViewModifier: ViewModifier {
  15. let color: UIColor
  16. func body(content: Content) -> some View {
  17. content
  18. .background(ModalColorView(color: color))
  19. }
  20. }
  21. extension View {
  22. /// Set transparent or custom color for a modal background (.screen, .fullScreenCover)
  23. func modalColor(_ color: UIColor = .clear) -> some View {
  24. self.modifier(ModalColorViewModifier(color: color))
  25. }
  26. }

字符串
像这样使用:

  1. .sheet(isPresented: $show) {
  2. YourModalView(isPresented: $show)
  3. // Zero args default is transparent (.clear)
  4. //.modalColor()
  5. // ..or specify a UIColor of choice.
  6. .modalColor(UIColor(white: 0.2, alpha: 0.3))
  7. }
  8. }

展开查看全部
kkih6yb8

kkih6yb87#

阿森伯格不希望他的答案被编辑,所以单独发布:

  1. struct ContentView: View {
  2. @SwiftUI.State var showSheet = false
  3. @SwiftUI.State var appear: Bool = false
  4. var body: some View {
  5. Button(action: {self. showSheet.toggle()}) {
  6. Text("Sheet")
  7. }.sheet(isPresented: $showSheet){
  8. Color.blue.opacity(0.5)
  9. .background(ClearBackgroundView(appear: $appear))
  10. .onAppear {DispatchQueue.main.async {appear = true}}
  11. }
  12. }
  13. }
  14. struct ClearBackgroundView: UIViewRepresentable {
  15. @Binding var appear: Bool
  16. class ClearView: UIView {
  17. override func didMoveToSuperview() {
  18. super.didMoveToSuperview()
  19. clearBackgroundColor()
  20. }
  21. func clearBackgroundColor() {
  22. var view: UIView? = self.superview?.superview
  23. while let subview = view {
  24. subview.backgroundColor = .clear
  25. view = subview.superview
  26. }
  27. }
  28. }
  29. func makeUIView(context: Context) -> ClearView {
  30. return ClearView()
  31. }
  32. func updateUIView(_ uiView: ClearView, context: Context) {
  33. uiView.clearBackgroundColor()
  34. }
  35. }

字符串

展开查看全部
amrnrhlw

amrnrhlw8#

在SwiftUI中,sheet修饰符通常用于呈现新视图,而不是样式化背景。要实现所需的不透明度背景颜色,您可以使用ZStack和Color视图的组合。下面是一个示例:

  1. import SwiftUI
  2. struct ContentView: View {
  3. @State private var isSheetPresented = false
  4. var body: some View {
  5. ZStack {
  6. Button(action: { self.isSheetPresented.toggle() }) {
  7. Text("Sheet")
  8. }
  9. if isSheetPresented {
  10. Color.yellow.opacity(0.5)
  11. .edgesIgnoringSafeArea(.all)
  12. .onTapGesture {
  13. self.isSheetPresented.toggle()
  14. }
  15. // Your sheet content goes here
  16. VStack {
  17. Text("Sheet Content")
  18. .foregroundColor(.white)
  19. // Add more content as needed
  20. }
  21. }
  22. }
  23. }
  24. }
  25. struct ContentView_Previews: PreviewProvider {
  26. static var previews: some View {
  27. ContentView()
  28. }
  29. }

字符串
在这个例子中,使用ZStack来覆盖按钮和背景颜色。当点击按钮时,会显示具有所需背景颜色和不透明度的Color视图,覆盖整个屏幕。您可以自定义VStack内部的内容,以显示所需的工作表内容。
另外,请注意在背景颜色上使用onTapGesture来在点击时关闭工作表。根据应用程序的设计调整颜色,不透明度和内容。

展开查看全部

相关问题