如何让 SwiftUI Shape View 符合相邻视图的尺寸

问题描述 投票:0回答:1

简单说明: 我显示了一个 SwiftUI Capsule() 以在 Text() 视图旁边显示状态颜色。到目前为止,在所有情况下,胶囊都在带有文本视图的 HStack 中使用。 我想让胶囊的高度与文本的高度相匹配。在某些情况下这并不是问题,例如在 List() 中。然而,在其他情况下,胶囊视图将比文本占用更多的垂直空间。

额外的复杂性 我已将 Capsule() 视图包装到名为 StatusCapsule() 的自定义视图中,以允许我采用颜色和宽度参数来更轻松地进行调整。我仅使用 Capsule() 视图进行了测试,并得到了相同的结果。 在我有问题的观点中,HStack 放置在 GridRow() 内、Grid() 内、ScrollView() 内、NavigationStack() 内。 我的困惑还来自于我的第一个和第二个 GridRow() 视图都有这个问题,但是,将 Grid() 放入 ScrollView() 后,顶部 GridRow() 输出 StatusCapsule() 视图符合我的预期,但第二个GridRow() 没有。

下面是 StatusCapsule 视图和简化的 AnalyticsView() 视图的代码,以及代码结果的屏幕截图

StatusCapsule() 查看:

struct StatusCapsule: View {
    
    var color: Color = .white
    var width: CGFloat = 4
    
    var body: some View {
        Capsule()
            .fill(color)
            .frame(width: width)
    }
}

带有网格和滚动视图的有问题的视图: 我用静态值替换了文本视图和颜色参数字段中的所有动态代码,以简化代码。我确实测试了这个简化的代码,并收到了与我的动态视图相同的结果,所以据我了解,两者基本上是相同的。

struct AnalyticsView: View {
    
    @State private var path = NavigationPath()
    @State private var nums: [String] = ["5","9","4","7","33","37","81"]

    var body: some View {
        NavigationStack(path: $path) {
            ScrollView {
                Grid(alignment: .center, horizontalSpacing: 5, verticalSpacing: 5) {
                    GridRow(alignment: .center) {
                        ZStack {
                            RoundedRectangle(cornerRadius: 20)
                                .foregroundStyle(Color(.secondarySystemBackground))
                                .padding(2)
                            VStack {
                                HStack {
                                    StatusCapsule(color: .cyan)
                                    StatusCapsule(color: .cyan)
                                    Text("Total Expected: $1,350.65")
                                        .font(.headline)
                                }
                                HStack {
                                    StatusCapsule(color: .cyan)
                                    Text("Total Completed: $25.44")
                                        .font(.subheadline)
                                    Text("|")
                                        .bold()
                                    StatusCapsule(color: .blue)
                                    Text("Total Invoiced: 45.67")
                                        .font(.subheadline)
                                }
                            }
                            .padding()
                        }.gridCellColumns(2)
                    } // Headline Cell
                    GridRow() {
                        ZStack {
                            RoundedRectangle(cornerRadius: 20)
                                .foregroundStyle(Color(.secondarySystemBackground))
                                .padding(2)
                            VStack(alignment: .leading) {
                                Text("In Progress: 5").font(.headline)
                                ForEach(nums.prefix(5), id: \.self) { num in
                                    HStack {
                                        StatusCapsule(color: .red)
                                        Text("\(num)")
                                    }
                                }
                            }
                            .padding(.vertical)
                            .scaledToFit()
                        }.gridCellColumns(1)
                        ZStack {
                            RoundedRectangle(cornerRadius: 20)
                                .foregroundStyle(Color(.secondarySystemBackground))
                                .padding(2)
                        }
                    }
                }
            }
            .navigationTitle("Analytics")
        }
    }
}

我一直在研究控制视图框架,除了深入研究 SwiftUI 之前的 UI 代码之外,还没有找到令我满意的解决方案。我希望胶囊视图动态地符合其关联的 HStack 中文本视图的高度。

我期待在网格的第一行中看到的结果,而且我也很困惑为什么放置在 ScrollView 中后两行之间会看到不同的结果。就这一点而言,当整个 Grid 未放置在 ScrollView 中时,顶部 GridRow 中的胶囊的行为与第二个 GridRow 中的胶囊完全相同。

swift swiftui
1个回答
0
投票
您所需的行为是滚动视图中网格单元中的默认行为,但胶囊被拉伸,因为

VStack

scaledToFit
。你应该删除它。

VStack(alignment: .leading) { Text("In Progress: 5").font(.headline) ForEach(nums.prefix(5), id: \.self) { num in HStack { StatusCapsule(color: .red) Text("\(num)") } } } .padding(.vertical) //.scaledToFit() // <---- remove this
输出:

enter image description here

ScrollView

“修复”了第一个网格行,因为滚动视图阻止其内容扩展以填充所有可用空间(毕竟,滚动视图中存在“无限空间”)。滚动视图的内容将根据其理想大小调整大小,您也可以使用 
fixedSize
 修饰符来实现。因此,如果您实际上不需要 
ScrollView
,您可以这样做

Grid { // ... } .fixedSize(horizontal: false, vertical: true)
    
© www.soinside.com 2019 - 2024. All rights reserved.