所以从技术上讲,我想显示一个加载屏幕视图。我正在使用fullScreenCover.
struct ContentView: View {
@State private var isLoading = false
var body: some View {
VStack {
Text("Hello there")
Button("Start loading") {
isLoading.toggle()
}
.fullScreenCover(isPresented: $isLoading) {
ZStack{
Color.black.opacity(0.5).edgesIgnoringSafeArea(.all)
VStack {
ProgressView()
Button("Stop loading") {
isLoading.toggle()
}
}
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
问题是我无法使这个加载屏幕半透明。sheet或popover以同样的方式行事。
Pov*_*las 19
建立在 f3dm76 答案之上:
我更改了它,这样后面的内容就不会闪烁(这发生在我身上,因为全屏覆盖后面加载了延迟图像)。另外,我想对全屏内容使用自定义过渡(或者在某些情况下根本没有动画),因此我也用这种方法删除了默认动画。
extension View {
func transparentNonAnimatingFullScreenCover<Content: View>(isPresented: Binding<Bool>, content: @escaping () -> Content) -> some View {
modifier(TransparentNonAnimatableFullScreenModifier(isPresented: isPresented, fullScreenContent: content))
}
}
private struct TransparentNonAnimatableFullScreenModifier<FullScreenContent: View>: ViewModifier {
@Binding var isPresented: Bool
let fullScreenContent: () -> (FullScreenContent)
func body(content: Content) -> some View {
content
.onChange(of: isPresented) { isPresented in
UIView.setAnimationsEnabled(false)
}
.fullScreenCover(isPresented: $isPresented,
content: {
ZStack {
fullScreenContent()
}
.background(FullScreenCoverBackgroundRemovalView())
.onAppear {
if !UIView.areAnimationsEnabled {
UIView.setAnimationsEnabled(true)
}
}
.onDisappear {
if !UIView.areAnimationsEnabled {
UIView.setAnimationsEnabled(true)
}
}
})
}
}
private struct FullScreenCoverBackgroundRemovalView: UIViewRepresentable {
private class BackgroundRemovalView: UIView {
override func didMoveToWindow() {
super.didMoveToWindow()
superview?.superview?.backgroundColor = .clear
}
}
func makeUIView(context: Context) -> UIView {
return BackgroundRemovalView()
}
func updateUIView(_ uiView: UIView, context: Context) {}
}
Run Code Online (Sandbox Code Playgroud)
小智 19
使用presentationBackground为模态框(fullScreenCover、sheet、popover)设置所需的背景。从文档中:
允许通过半透明样式显示演示文稿背后的视图。
struct ContentView: View {
@State private var isLoading = false
var body: some View {
VStack {
Text("Hello there")
Button("Start loading") { isLoading.toggle() }
.fullScreenCover(isPresented: $isLoading) {
ZStack{
VStack {
ProgressView()
Button("Stop loading") { isLoading.toggle() }
}
}
.presentationBackground(.black.opacity(0.5))
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
可用性
@available(iOS 16.4, macOS 13.3, tvOS 16.4, watchOS 9.4, *)
Run Code Online (Sandbox Code Playgroud)
Asp*_*eri 17
这是可能的方式的演示。您可以根据需要调整视觉效果参数。
使用 Xcode 12 / iOS 14 测试。
// ... other code
.fullScreenCover(isPresented: $isLoading) {
ZStack{
Color.black.opacity(0.5).edgesIgnoringSafeArea(.all)
VStack {
ProgressView()
Button("Stop loading") {
isLoading.toggle()
}
}
}
.background(BackgroundBlurView())
}
}
}
}
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) {}
}
Run Code Online (Sandbox Code Playgroud)
Ahm*_*san 12
我找到了这个更干净的解决方案,可以解决清晰背景中的闪烁问题。
struct ClearBackgroundView: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
return InnerView()
}
func updateUIView(_ uiView: UIView, context: Context) {
}
private class InnerView: UIView {
override func didMoveToWindow() {
super.didMoveToWindow()
superview?.superview?.backgroundColor = .clear
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法
PresenterView()
.fullScreenCover(isPresented: $isPresented) {
PresentedView()
.background(ClearBackgroundView())
}
Run Code Online (Sandbox Code Playgroud)
更新:请使用上面 Povilas 的答案以避免屏幕闪烁问题
Asperi 的答案很漂亮,但如果您希望背景透明而不模糊,可以按以下方法修改它。为了方便起见,我还将代码移至修饰符中。(Xcode 13.3、iOS 15.4.1)
extension View {
func transparentFullScreenCover<Content: View>(isPresented: Binding<Bool>, content: @escaping () -> Content) -> some View {
fullScreenCover(isPresented: isPresented) {
ZStack {
content()
}
.background(TransparentBackground())
}
}
}
struct TransparentBackground: UIViewRepresentable {
func makeUIView(context: Context) -> UIView {
let view = UIView()
DispatchQueue.main.async {
view.superview?.superview?.backgroundColor = .clear
}
return view
}
func updateUIView(_ uiView: UIView, context: Context) {}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2048 次 |
| 最近记录: |