List 内的 CustomCellView 不可调整大小,使用 SwiftUI

CustomCellView inside List is not resizable, using SwiftUI

我尝试使用 SwiftUI 设计自定义列表项,但无法调整大小。

  1. 红色突出显示的是要调整大小的动态内容Text。所以 CustomCell 应该根据内容调整大小(红色突出显示)。
  2. 根据模型 ItemModel 中的 属性 isTranslation 可以隐藏所有三个按钮。所以再次 CustomCell 应该调整大小。

请帮忙。提前致谢。

示例屏幕截图 -

代码如下:-

父 ContentView

struct ParentView: View {
    
    private let list = ItemModel.list
    
    var body: some View {
        
        NavigationView {
            
            ScrollView {
                
                ForEach(list, id: \.self) { item in
                    
                    CustomCell(item: item)
                        .padding(.top, 4)
                        .padding(.horizontal, 8)
                        .cornerRadius(8)
                        .shadow(color: .black, radius: 4, x: 1, y: 1)
                }
            }
            .navigationBarTitle("Nav Title", displayMode: .automatic)
        }
    }
}

型号

struct ItemModel: Decodable, Hashable {
    var sno: String
    var content: String
    var reference: String
    var isTranslation: Bool
    
    static let list: [ItemModel] = Bundle.main.decode(fileName: "items.json")
}

自定义单元格视图

struct CustomCell: View {
    
    var item: ItemModel
    
    var body: some View {
        
        VStack(spacing: 16) {
            VStack {
                Text("\(item.sno)")
                    .frame(maxWidth: .infinity, alignment: .center)
                    .padding(.vertical, 8)
                    .background(Color.gray)
                    .foregroundColor(.white)
                    .cornerRadius(4)
                    .shadow(color: .gray, radius: 2, x: 1, y: 1)
            }
            VStack(spacing: 16) {
                Text("\(item.content)")
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 150, maxHeight: .infinity, alignment: .topLeading)
                    .multilineTextAlignment(.center)
                Text("\(item.reference)")
                    .foregroundColor(.red)
                    .frame(maxWidth: .infinity, alignment: .leading)
                    .padding(.leading, 16)
            }
            
            if item.isTranslation {
                HStack {
                    Spacer()
                    TextButtonView(title: "Button 1", color: Color.lightGray, radius: 1)
                    Spacer()
                    TextButtonView(title: "Button 2", color: Color.lightGray, radius: 1)
                    Spacer()
                    TextButtonView(title: "Button 3", color: Color.lightGray, radius: 1)
                    Spacer()
                }
            }
        }
//        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 150, maxHeight: .infinity, alignment: .topLeading)
        .padding(8)
        .multilineTextAlignment(.center)
        .background(Color.white)
    }
}

struct CustomCell_Previews: PreviewProvider {
    static var previews: some View {
        CustomCell(item: ItemModel.list.first!)
    }
}

底部 3 个按钮视图

struct CustomTextButtonView: View {
    
    var title: String
    var color: Color
    var radius: CGFloat
    
    var body: some View {
        
        Text(title)
            .frame(maxWidth: .infinity, alignment: .center)
            .padding(.vertical, 8)
            .background(color)
            .cornerRadius(4)
            .shadow(color: .gray, radius: radius, x: 1, y: 1)
    }
}

Json 文件:-

[
  {
    "sno": "1",
    "content": "Now, let’s add a brand new view to our project which is going to be presented when user taps the bell button.",
    "reference": "SheetView",
    "isTranslation": true
  },
  {
    "sno": "2",
    "content": "Now, let’s add a brand new view to our project which is going to be presented when user taps the bell button. We’re going to call it a SheetView and it’s also going to be a NavigationView with a title. In this case, the title of the navigation bar is styled to be displayed inline (in the middle of the navigation bar)",
    "reference": "let’s add a brand new view",
    "isTranslation": true
  },
  {
    "sno": "3",
    "content": "SwiftUI’s sheets are used to present new views over existing ones, while still allowing users to drag down to dismiss the new view when they are ready.         To use a sheet, give it something to show (some text, an image, a custom view, etc), add a Boolean that defines whether the detail view should be showing, then attach it to your main view as a modal sheet.         For example, this creates a simple detail view, then presents it from ContentView when a button is tapped:",
    "reference": "Hello",
    "isTranslation": false
  }
]

不要在文本中使用“minHeight: 150” 无论文本多短,它至少需要 150 高度。删除 minHeight,它将正常工作。

对于无限行的文本,你可以使用这个

Text("")
 .fixedSize(horizontal: false, vertical: true)