SwiftUI中的内容优先行为

SwiftUI中的内容优先行为,swiftui,Swiftui,我有一个列表由单元格组成,每个单元格包含一个图像和一列文本,我希望以特定的方式进行布局。图像位于左侧,占据四分之一的宽度。文本的剩余空间,左对齐 这是我得到的代码: struct TestCell:视图{ let模型:ModelStruct var body:一些观点{ HStack{ 图像(“旗帜”) .可调整大小() .aspectRatio(内容模式:.fit) .frame(宽度:UIScreen.main.bounds.size.width*0.25) VStack(对齐:。前导,间距

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

这是我得到的代码:

struct TestCell:视图{
let模型:ModelStruct
var body:一些观点{
HStack{
图像(“旗帜”)
.可调整大小()
.aspectRatio(内容模式:.fit)
.frame(宽度:UIScreen.main.bounds.size.width*0.25)
VStack(对齐:。前导,间距:5){
案文(“国家:摩尔多瓦”)
正文(“大写:Chișinău”)
文本(“货币:卢布”)
}
.frame(最小宽度:0,最大宽度:。无穷大,对齐:。前导)
}
}
}
结构TestCell\u预览:PreviewProvider{
静态var预览:一些视图{
TestCell()
.previewLayout(.sizeThatFits)
.previewDevice(“iPhone 11”)
}
}
这里有两个例子:

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

$1M问题-如何使单元格高度紧靠文本(如第二幅图像)而不发生变化,而是在分配的矩形内以缩放比例缩小图像

注意

  • 文本的高度可以变化,因此没有硬编码
  • 无法使用
    PreferenceKey
    s使其工作,因为单元格将是列表的一部分,我试图了解有关单元格重用的一些特殊行为,并且当两个连续单元格具有相同高度时,
    onPreferenceChange
    不会被调用。要展示所有这些组合行为,请确保在测试模型时,模型在单元之间有所不同

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

    struct SizePreferenceKey: PreferenceKey {
        typealias Value = CGSize
        static var defaultValue: Value = .zero
    
        static func reduce(value _: inout Value, nextValue: () -> Value) {
            _ = nextValue()
        }
    }
    
    struct ContentView6: View {
    
        @State var childSize: CGSize = .zero
        
        var body: some View {
            HStack {
                Image("image1")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: UIScreen.main.bounds.size.width * 0.25, height: self.childSize.height)
                VStack(alignment: .leading, spacing: 5) {
                    Text("Country: Moldova")
                    Text("Capital: Chișinău")
                    Text("Currency: Leu")
                }
                .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
                .background(
                      GeometryReader { proxy in
                        Color.clear.preference(key: SizePreferenceKey.self, value: proxy.size)
                       }
                     )
            }
            .onPreferenceChange(SizePreferenceKey.self) { preferences in
              self.childSize = preferences
            }
            .border(Color.yellow)
    
        }
          
    
    }
    
    看起来像这样。。当然,您可以为图像应用不同的纵横比


    我真的不明白你想达到什么目的。即使我们拥抱VStack(这并不难),所有内部文本仍保持在中心位置,因为它们不是一个文本(要拥抱),它们是3个不同的视图,并将按照您指定的间距5保持在原来的位置。如果您想要分发文本子视图,那么应该如何分发,因为存在变体,它们取决于VStack中可以包含多少子视图。简言之,存在歧义。我认为他只是想让文本/VStack确定整个HStack的高度,然后相应地剪切图像。是的,没错,在列表行的视图上使用PreferenceKey有问题,这使得
    onPreferenceChange
    不会对每个单元格触发,图像的高度为0。我理解的关键是:1
    onPreferenceChange
    只有在高度变化时才会被调用(我假设是因为首选项有一个单态存储)。2.对于您的示例,即使它没有变化,也会正确呈现,因为列表似乎重用了相同的行。尝试在视图中放置一个跨行更改的模型,您将了解我的意思。我会更新这个问题来强调这一点。对不起,如果我误导了你,首先隐藏了一些信息。这不是故意的。我仍然在探索SwiftUI的所有黑暗角落。