当 TileView SwiftUI 中文本出现两行时,图像调整未固定到位置

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

我创建了一个 CardView/Tile 视图来显示为两列。我根据不同设备的屏幕尺寸计算了cardView的宽度和高度。

我面临的问题是图像的调整。我在图像下方还有一段文字。 整体图像固定在其位置,但每当文本出现两行

limitline(2)
时,图像几乎不会向上(顶部)位置移动。我设置了宽高比,但它无法正常工作。

请帮我看看我到底做错了什么。我可以像卡片/平铺视图一样根据屏幕尺寸设置图像吗?您可以看到第一个图块图像已向上移动。

代码

import SwiftUI

struct TileView: View {
    @StateObject var viewModel: CartViewModel
    
    // MARK: - Constants
    private struct ViewConstants {
        static let screenWidth = Constants.DeviceConfig.screenWidth
        static let cardRatio = 133.0/148.0
        static let cardWidth = screenWidth / 2 - 24
        static let cardHeight = cardWidth/cardRatio
        
        static let imageWidth: CGFloat = 106
        static let imageHeight: CGFloat = 106
    }
    
    var body: some View {
            VStack(spacing: 8) {
                Image(viewModel.image)
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(height: ViewConstants.imageHeight)
                
                Text(viewModel.title)
                    .lineLimit(2)
                    .multilineTextAlignment(.center)
                    .padding(.horizontal, 16)
            }
            .frame(width: ViewConstants.cardWidth, height: ViewConstants.cardHeight)
            .background(Color.gray)
            .cornerRadius(10)
    }
}

图片TileView

ios swiftui cardview
1个回答
0
投票

发生这种情况是因为当文本超过两行时,图像和文本的

VStack
具有更高的高度。

您正在

VStack
上设置一个框架,如下所示:

.frame(width: ViewConstants.cardWidth, height: ViewConstants.cardHeight)

这里的对齐方式是

.center
默认的,所以
VStack
的中间垂直居中。这意味着,当有两行文本时,图像会比只有一行文本时高一点。

这里有两种修复方法:

1。对文本应用最小高度

通过设置文本的最小高度,您可以确保它始终占据足够的空间以延伸超过两行:

Text(title)
    .lineLimit(2)
    .multilineTextAlignment(.center)
    .padding(.horizontal, 16)
    .frame(minHeight: 40, alignment: .top) // <- HERE

2。使用隐藏文本建立足迹

如果您不喜欢使用固定的最小高度,那么您可以通过使用一些隐藏文本来确定所需的最小高度。然后您可以在叠加层中显示实际(可见)文本:

Text(".\n.")
    .hidden()
    .frame(maxWidth: .infinity)
    .overlay(alignment: .top) {
        Text(title)
            .lineLimit(2)
            .multilineTextAlignment(.center)
            .padding(.horizontal, 16)
    }

隐藏文本由一个点、一个换行符和另一个点组成。这就是查找两行文本所需的高度所需的全部内容。

Screenshot

如果您希望图像更靠近垂直中心,那么您可以在框架上使用

.bottom
对齐:

Image(viewModel.image)
    .resizable()
    .aspectRatio(contentMode: .fit)
    .frame(height: ViewConstants.imageHeight, alignment: .bottom) // UPDATED

或者,只需在其上方添加一些填充:

Image(...)
    // other modifiers as before
    .padding(.top, 20)
© www.soinside.com 2019 - 2024. All rights reserved.