带有 .fill ContentMode 的 SwiftUI AsyncImage 覆盖 ZStack iOS-17 中的按钮

标签 swiftui zstack swiftui-asyncimage

我正在开发一个 SwiftUI View ,该 View 显示使用 AsyncImage 从 URL 获取的图像。我希望图像填满整个屏幕,并且我在 ZStack 中的图像底部覆盖了一排按钮。但是,当我将 AsyncImage 的 contentMode 设置为 .fill 时,按钮不可见。将 contentMode 更改为 .fit 会使按钮出现,但图像不再按需要填充整个屏幕。

以下是演示该问题的代码片段:

import SwiftUI

struct ImageViewTest: View {
    private let wallpaperPath = "https://w.wallhaven.cc/full/7p/wallhaven-7pmj9o.jpg"
    
    var body: some View {
        ZStack(alignment: .center) {
            AsyncImage(url: URL(string: wallpaperPath)) { phase in
                switch phase {
                case .empty:
                    ProgressView()
                case .failure:
                    Text("Failed to fetch image")
                case .success(let image):
                    image
                        .resizable()
                        .aspectRatio(contentMode: .fill) // Changing this to .fit shows the buttons
                        .clipped()
                @unknown default:
                    fatalError()
                }
            }
            .ignoresSafeArea(.all)
            
            VStack {
                Spacer()
                HStack {
                    Button(action: {}) {
                        Image(systemName: "square.and.arrow.down")
                            .foregroundStyle(.blue)
                    }
                    Spacer()
                    Button(action: {}) {
                        Image(systemName: "heart")
                            .foregroundStyle(.blue)
                    }
                    Spacer()
                    Button(action: {}) {
                        Image(systemName: "arrow.down.circle")
                            .foregroundStyle(.blue)
                    }
                }
                .padding()
                .background(.ultraThinMaterial)
                .cornerRadius(10)
            }
        }
    }
}

#Preview {
    ImageViewTest()
}


我的目标是让图像填满整个屏幕,同时保持按钮在底部可见。对于在使用 .fill 作为 contentMode 时可能导致按钮被覆盖的任何建议或见解,我将不胜感激。

  • 将contentMode从.fill改为.fit,显示按钮,但不满足图像填满屏幕的要求。

最佳答案

这是因为图像导致 ZStack宽度溢出屏幕,您需要以某种方式防止这种情况发生。

iOS 17

如果您的目标系统是 iOS 17 或更高版本,则向 AsyncImage 添加以下修饰符就足够了:

.containerRelativeFrame(.horizontal)

iOS 13 或更高版本

一种方法是在 VStack 上使用 background 修饰符,而不是使用 ZStack,例如:

VStack { ,,, }
    .background {
        AsyncImage(url: URL(string: wallpaperPath)) { phase in ,,, }
        ,,,
    }

上述两种方法都会导致 View 显示如下:

Demo


关于带有 .fill ContentMode 的 SwiftUI AsyncImage 覆盖 ZStack iOS-17 中的按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77640940/

相关文章:

swift - 圆形 LinearGradient 上的 ContextMenu 在 SwiftUI 中产生锐边

ios - 如何设置 UIHostingController 背景颜色清除?

ios - 如何删除 ZStack SwiftUI 中的填充

swift - 具有环绕和动态高度的SwiftUI HStack

ios - 与 AsyncImage iOS 15 匹配的几何效果

ios - 无法推断复杂的闭包返回类型 SwiftUI ForEach

ios - SwiftUI:自定义按钮无法识别具有清晰背景和 buttonStyle 的触摸

ios - 当 ForEach 中发生 onDelete 时如何更新其他 CoreData?