SwiftUI中如何裁剪文本替代省略号?复刻iOS提醒APP滑动删除效果
问题:SwiftUI阻止文本显示省略号,实现iOS提醒APP滑动删除裁剪效果
我想复刻iOS提醒APP中滑动删除控件的完整外观与交互效果,该控件在空间不足时会直接裁剪文本,而非显示省略号。但我自行实现的版本会出现省略号,效果对比:
- 提醒APP样式:

- 我的实现样式:

我的实现代码如下:
struct CroppedText: View { var text: String var color: Color var body: some View { Text(text) // How to avoid the "..."? .lineLimit(1) .foregroundStyle(.white) .frame(maxWidth: .infinity, maxHeight: .infinity) .background(color) } } struct TripleText: View { @State private var totalWidth = 120.0 var body: some View { VStack { HStack(spacing: 0) { CroppedText(text: "Details", color: .secondary) CroppedText(text: "Flag", color: .orange) CroppedText(text: "Delete", color: .red) } .frame(width: totalWidth, height: 50) HStack { Text("Width: ") Slider(value: $totalWidth, in: 1...300) } } .padding() } }
我推测解决方案需要避免文本在空间不足时居中,或许需要用ZStack替代HStack,并配合顶层的.clipped()修饰符,请问有可行的实现建议吗?
解决方案
你的思路方向是对的,核心是让文本不受容器宽度约束,再通过父容器裁剪超出部分,以下是两种可行实现:
方法1:ZStack+clipped实现原生对齐与裁剪
修改CroppedText,让文本左对齐并自由绘制,超出部分被裁剪:
struct CroppedText: View { var text: String var color: Color var body: some View { ZStack(alignment: .leading) { color // 背景占满容器 Text(text) .foregroundStyle(.white) .padding(.horizontal, 16) // 还原原生按钮的文本内边距 } .clipped() // 裁剪超出ZStack范围的文本 } } struct TripleText: View { @State private var totalWidth = 120.0 var body: some View { VStack { HStack(spacing: 0) { CroppedText(text: "Details", color: .secondary) CroppedText(text: "Flag", color: .orange) CroppedText(text: "Delete", color: .red) } .frame(width: totalWidth, height: 50) HStack { Text("Width: ") Slider(value: $totalWidth, in: 1...300) } } .padding() } }
原理说明:
- 原代码中
Text被.frame(maxWidth: .infinity)约束,空间不足时SwiftUI自动添加省略号;现在让文本不受宽度限制,超出容器的部分被.clipped()裁掉。 ZStack(alignment: .leading)让文本左对齐,和原生提醒APP的滑动删除按钮样式完全一致。- 添加水平内边距,还原系统控件的文本间距,更贴近原生体验。
方法2:fixedSize强制文本保持原始宽度
给Text添加.fixedSize属性,让文本不自动换行或截断,再配合裁剪:
struct CroppedText: View { var text: String var color: Color var body: some View { Text(text) .foregroundStyle(.white) .lineLimit(1) .fixedSize(horizontal: true, vertical: false) // 强制文本保持单行原始宽度 .frame(maxHeight: .infinity) .background(color) .clipped() } }
这个方法同样能避免省略号,效果与方法1相近,适合不想重构ZStack的场景。
内容的提问来源于stack exchange,提问作者Curious Jorge
相关产品推荐
相关产品推荐

