Automatically adjustable view height based on text height in SwiftUI

前端 未结 1 1049
花落未央
花落未央 2020-12-11 10:47

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.

I tried a

相关标签:
1条回答
  • 2020-12-11 11:22

    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()
        }
    }
    
    
    0 讨论(0)
提交回复
热议问题