如何根据 SwiftUI 中的叠加内容扩展形状的高度

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

我是 SwiftUI 的新手,遇到了一个相对简单的问题。我有一个 RecipeCard 组件,它有一个图像和底部矩形部分,其中有食谱的标题和作者的名字。

现在,如果标题或作者姓名超出文本框的最大宽度,它会用“名称的一部分...”切断溢出。我希望标题和作者姓名扩展到不同的行(我已经实现了)但也推出了底部矩形部分的高度。

我的主要方法是为矩形设置最大高度。但是,当我设置最大高度时,矩形似乎总是达到最大高度,即使没有内容将其向下推也是如此。虽然在下面的代码中很明显 VStack 中的 Spacer() 最大化了垂直空间,但我尝试了其他变体但遇到了同样的问题。当文本需要换行时,有没有人有任何简单的方法来调整底部矩形的高度(同时也推出外圆角矩形)?

这是我的组件代码:

        RoundedRectangle(cornerRadius: 10)
            .strokeBorder(Color.black, lineWidth: 1)
            .background(RoundedRectangle(cornerRadius: 10).fill(.white))
            .frame(width: 132, height: 180)
            .padding(-1)
            .overlay {
                VStack (spacing: 0) {
                    Image("coq-au-vin")
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                        .frame(height: 132)
                        .clipShape(RoundedRectangle(cornerRadius: 10, style: .continuous))
                        .padding(.bottom, -16)
                        
                    Rectangle()
                        .fill(Color(.white))
                        .frame(height: 48)
                        .overlay {
                            VStack (alignment: .leading, spacing: 4) {
                                Text(recipeName)
                                    .font(.custom("Inter-Regular", size: 13))
//                                        .lineLimit(nil)
//                                        .fixedSize(horizontal: false, vertical: true)
                                Text(recipeAuthor)
                                    .font(.custom("Inter-Regular", size: 11))
//                                        .lineLimit(nil)
//                                        .fixedSize(horizontal: false, vertical: true)
                            }
                            .frame(maxWidth: .infinity, alignment: .leading)
                            .padding([.top, .leading, .trailing], 8)
                        }
                        
                    Spacer()
                }
            }
swift swiftui frame mobile-development
2个回答
0
投票

lorem ipsum 的技巧是一个很好的技巧——如果您让视图的主要内容在尽可能少的

.frame
约束下找到自己的大小,它可能会更好。然后在其后面应用背景(如果需要)和边框作为覆盖。背景和叠加层自动采用它们所应用的视图的大小。

希望以下内容接近您的要求:

struct ContentView: View {
    let recipeName = "Coq Au Vin With Lots Of Tasty Bits"
    let recipeAuthor = "Recipe Tin Eats With All His Mates"
    var body: some View {
        VStack(spacing: 0) {
            Image(systemName: "fork.knife.circle")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(height: 132)
                .background(Color.yellow)
            VStack(alignment: .leading, spacing: 4) {
                Text(recipeName)
                    .font(.custom("Inter-Regular", size: 13))
                Text(recipeAuthor)
                    .font(.custom("Inter-Regular", size: 11))
            }
            // Force multi-line instead of truncation of text
            .fixedSize(horizontal: false, vertical: true)
            .padding(8)
        }
        .frame(width: 132)
        .background(Color.white)
        .cornerRadius(10)
        .overlay(
            RoundedRectangle(cornerRadius: 10)
                .strokeBorder(Color.black, lineWidth: 1)
        )
    }
}


0
投票

叠加层和背景的大小并没有真正的发言权,它们只是适合它们所附加的视图的大小。

对于您的情况,我建议您完全不要使用叠加层(可能只是用于边框)并使用 VStack 作为主要内容。

  • 图像仍然需要调整大小和纵横比。
  • minHeight 可能不需要,但它似乎符合您的要求。

这是我的意思的粗略示例:

var body: some View {
    VStack(spacing: 0) {
        image
            .frame(maxHeight: 130, alignment: .top)
        text
            .padding(4)
            .frame(minHeight: 60)
            .background(Color.white)
    }
    .frame(width: 132)
    .clipShape(shape)
    .overlay(shape.stroke())
}

private var shape: some InsettableShape {
    RoundedRectangle(cornerRadius: 10, style: .continuous)
}
© www.soinside.com 2019 - 2024. All rights reserved.