You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中如何裁剪文本替代省略号?复刻iOS提醒APP滑动删除效果

问题:SwiftUI阻止文本显示省略号,实现iOS提醒APP滑动删除裁剪效果

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

  • 提醒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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 08:41:10