簡體   English   中英

如何一致地分離 HStack 上的元素

[英]How to consistently separate elements on a HStack

我在HStack上有一組元素,它們由一個圓圈和一些 label 文本組成。 這些元素之間有一個分隔。

元素的圖片

一切都按預期工作,直到其中一個標簽大於圓圈。 然后,文本增加了元素的實際寬度,使圓圈之間的可見分離關閉。

在此處輸入圖像描述

有什么方法可以均勻地分開圓圈,忽略文字?

struct Item: View {
    let color: Color
    let label: String
    
    var body: some View {
        VStack {
            Circle()
                .fill(color)
                .frame(width: 40, height: 40)
            Text(label)
        }
    }
}

struct ItemSeparation: View {
    var body: some View {
        HStack(alignment: .top, spacing: 30) {
            Item(color: .yellow, label: "Berlin")
            Item(color: .green, label: "Copenhagen")
            Item(color: .blue, label: "Madrid")
            Item(color: .purple, label: "Helsinki")
        }
    }
}

這兩種解決方案有不同的折衷方案。 您需要決定會發生什么,例如,如果視圖對於基於最長 label 的父視圖來說太寬。 選項 1 換行文本。 選項 2 使視圖擴展到其父級之外。

選項1:

使用LazyVGrid

struct ContentView: View {
    let columns = [
            GridItem(.flexible()),
            GridItem(.flexible()),
            GridItem(.flexible()),
            GridItem(.flexible()),
        ]

    
    var body: some View {
        LazyVGrid(columns: columns, spacing: 30) {
            Item(color: .yellow, label: "Berlin")
            Item(color: .green, label: "Copenhagen")
            Item(color: .blue, label: "Madrid")
            Item(color: .purple, label: "Helsinki")
        }
    }
}

選項#2:

使用PreferenceKeyGeometryReader獲取最寬View的大小並將更改傳播回父級。

struct Item: View {
    let color: Color
    let label: String
    let width: CGFloat
    
    var body: some View {
        VStack {
            Circle()
                .fill(color)
                .frame(width: 40, height: 40)
            Text(label)
        }
        .border(Color.blue)
        .background(
            GeometryReader {
                Color.clear.preference(key: ViewWidthKey.self,
                                   value: $0.size.width)
            }.scaledToFill()
        )
        .frame(width: width)
    }
}

struct ViewWidthKey: PreferenceKey {
    static var defaultValue: CGFloat { 0 }
    static func reduce(value: inout Value, nextValue: () -> Value) {
        let nextValue = nextValue()
        guard nextValue > value else { return }
        value = nextValue
    }
}

struct ContentView: View {
    @State private var maxWidth : CGFloat = 0
    
    var body: some View {
        HStack(alignment: .top, spacing: 30) {
            Item(color: .yellow, label: "Berlin", width: maxWidth)
            Item(color: .green, label: "Copenhagen", width: maxWidth)
            Item(color: .blue, label: "Madrid", width: maxWidth)
            Item(color: .purple, label: "Helsinki", width: maxWidth)
        }.onPreferenceChange(ViewWidthKey.self) { width in
            self.maxWidth = width
            print(width)
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM