如何在SwiftUI中实现文本内容的展开/收起功能
SwiftUI实现文本超过指定高度时的展开/收起功能
要实现这个需求,核心是先测量文本的实际高度,判断是否超过阈值后再决定是否显示切换按钮,同时通过状态控制文本的折叠/展开状态,具体实现如下:
第一步:定义状态变量
在视图中添加两个@State变量,分别控制文本的折叠状态,以及是否需要显示切换按钮:
@State private var isCollapsed = true @State private var shouldShowToggleButton = false private let maxCollapsedHeight: CGFloat = 200 // 设定折叠状态的最大高度
第二步:完整视图实现
把文本和按钮整合到VStack中,通过GeometryReader测量文本高度,控制显示逻辑:
var body: some View { VStack(alignment: .leading) { Text(message) .font(.light16) .foregroundColor(.black) .multilineTextAlignment(.leading) .padding(.bottom, 8) // 控制文本的高度:折叠时限制最大高度,展开时不限制 .frame(maxHeight: isCollapsed ? maxCollapsedHeight : .infinity) .clipped() // 超出部分截断 // 通过背景的GeometryReader测量文本实际高度 .background( GeometryReader { proxy in Color.clear .onAppear { // 文本渲染完成后,判断实际高度是否超过阈值 shouldShowToggleButton = proxy.size.height > maxCollapsedHeight } .onChange(of: message) { _ in // 如果文本内容变化,重新判断高度 shouldShowToggleButton = proxy.size.height > maxCollapsedHeight } } ) // 只有当文本高度超过阈值时,才显示切换按钮 if shouldShowToggleButton { Button { isCollapsed.toggle() } label: { Text(isCollapsed ? "展开全文" : "收起全文") .font(.bold14) .foregroundColor(.blue) .padding(.bottom, 8) } } // 原视图中的其他内容... // ... } }
关键逻辑说明
- 测量文本高度:利用
GeometryReader作为文本的背景,因为背景会完全贴合文本的实际尺寸,所以能准确获取文本的高度。在onAppear和文本内容变化时(onChange(of: message)),判断高度是否超过设定的200px,从而决定是否显示切换按钮。 - 控制文本折叠/展开:通过
frame(maxHeight:)来限制文本高度,折叠时设置为200px,同时用.clipped()把超出部分截断;展开时设为.infinity,让文本完整显示。 - 按钮显示逻辑:只有当文本实际高度超过阈值时,才渲染切换按钮,避免内容较短时出现多余按钮。
内容的提问来源于stack exchange,提问作者Wonton
相关产品推荐
相关产品推荐

