【问题标题】:How do I setup ZStack with Image filled to the widget bounds?如何使用填充到小部件边界的图像设置 ZStack?
【发布时间】:2021-04-17 20:45:38
【问题描述】:

我的代码如下所示:

    ZStack {
        
        NetworkImage(url: url)
        VStack(alignment: .trailing, spacing: 5) {
            Spacer()
            Text("this is my quite long title here")
                    .font(.title)
                    .bold()
                    .foregroundColor(.white)
                    .lineLimit(nil)
                    .multilineTextAlignment(.trailing)
            Text("subtitle this is my long long subtitle to create multiply lines")
                    .font(.caption)
                    .foregroundColor(.white)
                    .lineLimit(nil)
                    .multilineTextAlignment(.trailing)
        }
        .padding()
    }

struct NetworkImage: View {
    let url: URL?
    var body: some View {
        if let url = url, let imageData = try? Data(contentsOf: url), let uiImage = UIImage(data: imageData) {
            Image(uiImage: uiImage)
                .resizable()
                .scaledToFill()
        }
    }
}

但这看起来很糟糕,这不是我需要实现的目标。

我需要使它与右侧和底部对齐,并从边缘进行一些填充。就这些。我该怎么做?

从@user1046037 更新后的答案看起来像:

【问题讨论】:

    标签: ios swift swiftui


    【解决方案1】:

    代码更改:

    1。 ZStack 对齐

    ZStack(alignment: Alignment(horizontal: .trailing, vertical: .bottom)) {
    

    2。在中心裁剪

    NetworkImage 中,在图片扩展中居中裁剪(提供代码)。

    感谢@vacawama How to center crop an image in SwiftUI

    完整代码:

    struct ContentView: View {
        var body: some View {
            ZStack(alignment: Alignment(horizontal: .trailing, vertical: .bottom)) {
                
                NetworkImage(url: URL(string: "https://unsplash.com/photos/KZv3Rb_OIXI/download?force=true"))
                VStack(alignment: .trailing, spacing: 5) {
                    Spacer()
                    Text("this is my quite long title here")
                            .font(.title)
                            .bold()
                            .foregroundColor(.white)
                            .lineLimit(nil)
                            .multilineTextAlignment(.trailing)
                    Text("subtitle this is my long long subtitle to create multiply lines")
                            .font(.caption)
                            .foregroundColor(.white)
                            .lineLimit(nil)
                            .multilineTextAlignment(.trailing)
                }
                .padding()
            }
        }
    }
    
    //Center Crop
    extension Image {
        func centerCropped() -> some View {
            GeometryReader { geo in
                self
                .resizable()
                .scaledToFill()
                .frame(width: geo.size.width, height: geo.size.height)
                .clipped()
            }
        }
    }
    
    struct NetworkImage: View {
        let url: URL?
        var body: some View {
            if let url = url, let imageData = try? Data(contentsOf: url), let uiImage = UIImage(data: imageData) {
                Image(uiImage: uiImage)
                    .centerCropped()
            }
        }
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    

    【讨论】:

    • 不,它不起作用...还是一样。看起来图像视图移动到了小部件边界之外。
    • 在 NetworkImage 中,您可以使用.scaledToFit() 代替.scaledToFill() 以及上述更改吗?
    • 更新了我的答案,只是为了确保我们在同一页面上,我不是在小部件上预览,但这是一张风景图片
    • 我更新了问题,但这不是我需要的,因为图像不会填满整个空间......
    • 通过在中心裁剪查看更新,感谢stackoverflow.com/questions/63651077/…
    【解决方案2】:

    带有ImageZStack 是问题所在。 ZStack 不是裁剪图像,它实际上是在增长以适应图像并延伸到小部件的边界之外。文本位于同一个 ZStack 内,因此它也会增长以填充可用空间。

    也许这有助于可视化问题(黑色圆形矩形是 widget 框架):

    解决方案

    将图像放在 VStack 的 .background 中:

    var body: some View {
    
        VStack(alignment: .trailing, spacing: 5) {
            Spacer()
            Text("this is my quite long title here")
                .font(.title)
                .bold()
                .foregroundColor(.white)
                .lineLimit(nil)
                .multilineTextAlignment(.trailing)
            Text("subtitle this is my long long subtitle to create multiply lines")
                .font(.caption)
                .foregroundColor(.white)
                .lineLimit(nil)
                .multilineTextAlignment(.trailing)
        }
        .padding()
        .frame(maxWidth: .infinity, maxHeight: .infinity)
        .background(NetworkImage(url: url))
    
    }
    
    struct NetworkImage: View {
        let url: URL?
        var body: some View {
            if let url = url, let imageData = try? Data(contentsOf: url), let uiImage = UIImage(data: imageData) {
                Image(uiImage: uiImage)
                    .resizable()
                    .scaledToFill()
            }
        }
    }
    

    【讨论】:

    • 感谢您的回答,但图片适合视图。没有填满整个空间...有什么可以设置 contentMode 像 .aspectFill 而不是 .aspectFit
    • 您是否使用原始帖子中的NetworkImagescaledToFill? (我更新了我的答案以澄清 NetworkImage 是什么)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多