如何根据 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
作为主要内容。

  • Image
    仍然需要调整大小和纵横比。
  • 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.