SwiftUI 中的内容拥抱优先行为

Ser*_*scu 5 swiftui

我有一个由单元格组成的列表,每个单元格包含一个图像和一列文本,我希望以特定方式对其进行布局。左侧图像,占宽度的四分之一。文本的剩余空间,左对齐。

这是我得到的代码:

struct TestCell: View {
    let model: ModelStruct

    var body: some View {
        HStack {
            Image("flag")
                .resizable()
                .aspectRatio(contentMode: .fit)
                .frame(width: UIScreen.main.bounds.size.width * 0.25)
            VStack(alignment: .leading, spacing: 5) {
                Text("Country: Moldova")
                Text("Capital: Chi?in?u")
                Text("Currency: Leu")
            }
            .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
        }
    }
}

struct TestCell_Previews: PreviewProvider {
    static var previews: some View {
        TestCell()
            .previewLayout(.sizeThatFits)
            .previewDevice("iPhone 11")
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有两个例子:

如您所见,整个单元格的高度根据图像的纵横比而变化。

100 万美元的问题 - 我们如何使单元格高度紧贴文本(如第二张图像中)而不发生变化,而是在分配的矩形内以scaleAspectFit方式缩小图像

笔记!

  1. 文本的高度可能会有所不同,因此无需进行硬编码。
  2. 无法使其与PreferenceKeys 一起使用,因为单元格将成为列表的一部分,并且我试图围绕单元格重用掌握一些特殊行为,并且onPreferenceChange在 2 个连续单元格具有相同高度时不会被调用。要展示所有这些组合行为,请确保您的模型在测试时因单元格而异。

dav*_*dev 2

这是一个可能的解决方案,但是它使用 VStack 的背景属性内的 GeometryReader 来检测它们的高度。然后将该高度应用于图像。我使用了SizePreferenceKey这个解决方案。

\n
struct SizePreferenceKey: PreferenceKey {\n    typealias Value = CGSize\n    static var defaultValue: Value = .zero\n\n    static func reduce(value _: inout Value, nextValue: () -> Value) {\n        _ = nextValue()\n    }\n}\n\nstruct ContentView6: View {\n\n    @State var childSize: CGSize = .zero\n    \n    var body: some View {\n        HStack {\n            Image("image1")\n                .resizable()\n                .aspectRatio(contentMode: .fit)\n                .frame(width: UIScreen.main.bounds.size.width * 0.25, height: self.childSize.height)\n            VStack(alignment: .leading, spacing: 5) {\n                Text("Country: Moldova")\n                Text("Capital: Chi\xc8\x99in\xc4\x83u")\n                Text("Currency: Leu")\n            }\n            .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)\n            .background(\n                  GeometryReader { proxy in\n                    Color.clear.preference(key: SizePreferenceKey.self, value: proxy.size)\n                   }\n                 )\n        }\n        .onPreferenceChange(SizePreferenceKey.self) { preferences in\n          self.childSize = preferences\n        }\n        .border(Color.yellow)\n\n    }\n      \n\n}\n
Run Code Online (Sandbox Code Playgroud)\n

看起来像这样..当然,您可以为图像应用不同的纵横比。

\n\n