在 SwiftUI 中根据文本高度自动调整视图高度 [英] Automatically adjustable view height based on text height in SwiftUI

查看:15
本文介绍了在 SwiftUI 中根据文本高度自动调整视图高度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在 SwiftUI 中创建一个视图,其中左侧图像的背景应根据右侧文本的高度垂直缩放.

I am trying to create a view in SwiftUI where the background of the image on the left should scale vertically based on the height of the text on the right.

我尝试了很多不同的方法,从 GeometryReader.layoutPriority(),但我没有设法让它们中的任何一个工作.

I tried a lot of different approaches, from GeometryReader to .layoutPriority(), but I haven't managed to get any of them to work.

当前状态:

期望状态:

我知道我可以通过对我发布的示例的 .frame(100) 进行硬编码来模仿该功能,但是由于右侧的文本是动态的,所以这行不通.

I know that I could imitate the functionality by hardcoding the .frame(100) for the example I posted, but as text on the right is dynamic, that wouldn't work.

这是截图中视图的完整代码:

This is full code for the view in the screenshot:

import SwiftUI

struct DynamicallyScalingView: View {
    var body: some View {
        HStack(spacing: 20) {
            Image(systemName: "snow")
                .font(.system(size: 32))
                .padding(20)
                .background(Color.red.opacity(0.4))
                .cornerRadius(8)

            VStack(alignment: .leading, spacing: 8) {
                Text("My Title")
                    .foregroundColor(.white)
                    .font(.system(size: 13))
                    .padding(5)
                    .background(Color.black)
                    .cornerRadius(8)
                Text("Dynamic text that can be of different leghts. Spanning from one to multiple lines. When it's multiple lines, the background on the left should scale vertically")
                    .font(.system(size: 13))
            }
        }
        .padding(.horizontal)
    }
}

struct DailyFactView_Previews: PreviewProvider {
    static var previews: some View {
        DynamicallyScalingView()
    }
}

推荐答案

这里是一个基于视图首选项键的解决方案.使用 Xcode 11.4/iOS 13.4 测试

Here is a solution based on view preference key. Tested with Xcode 11.4 / iOS 13.4

struct DynamicallyScalingView: View {
    @State private var labelHeight = CGFloat.zero     // << here !!

    var body: some View {
        HStack(spacing: 20) {
            Image(systemName: "snow")
                .font(.system(size: 32))
                .padding(20)
                .frame(minHeight: labelHeight)       // << here !!
                .background(Color.red.opacity(0.4))
                .cornerRadius(8)

            VStack(alignment: .leading, spacing: 8) {
                Text("My Title")
                    .foregroundColor(.white)
                    .font(.system(size: 13))
                    .padding(5)
                    .background(Color.black)
                    .cornerRadius(8)
                Text("Dynamic text that can be of different leghts. Spanning from one to multiple lines. When it's multiple lines, the background on the left should scale vertically")
                    .font(.system(size: 13))
            }
            .background(GeometryReader {      // << set right side height
                Color.clear.preference(key: ViewHeightKey.self, 
                    value: $0.frame(in: .local).size.height) 
            })
        }
        .onPreferenceChange(ViewHeightKey.self) { // << read right side height
            self.labelHeight = $0        // << here !!
        }
        .padding(.horizontal)
    }
}

struct ViewHeightKey: PreferenceKey {
    static var defaultValue: CGFloat { 0 }
    static func reduce(value: inout Value, nextValue: () -> Value) {
        value = value + nextValue()
    }
}

这篇关于在 SwiftUI 中根据文本高度自动调整视图高度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆