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

SwiftUI音乐播放器:实现跑马灯文本截断后从另一侧重新滚动

音乐播放器跑马灯文本实现方案

要实现文本到达容器右侧后截断并从左侧重新出现的跑马灯效果,需要先计算文本与容器的宽度差,再基于这个差值设置精准的动画偏移量,同时只在文本过长时触发动画。以下是优化后的代码:

首先定义一个PreferenceKey来获取文本的尺寸:

private struct TextWidthKey: PreferenceKey {
    static var defaultValue: CGFloat = 0
    static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value = nextValue()
    }
}

然后替换原有的VStack部分,实现自适应的跑马灯:

@State private var scrollOffset: CGFloat = 0
@State private var textWidth: CGFloat = 0
private let containerWidth: CGFloat = 100

VStack(alignment: .leading) {
    // 跑马灯文本容器
    ZStack(alignment: .leading) {
        Text(album.songs.title ?? "")
            .font(.system(size: 13))
            .foregroundColor(.white)
            .fixedSize(horizontal: true, vertical: false)
            .background(
                GeometryReader { proxy in
                    Color.clear
                        .preference(key: TextWidthKey.self, value: proxy.size.width)
                }
            )
            .offset(x: scrollOffset)
            .onPreferenceChange(TextWidthKey.self) { newWidth in
                textWidth = newWidth
                // 文本过长时启动动画
                if newWidth > containerWidth {
                    let duration = newWidth / 30 // 控制滚动速度,30为每秒滚动的像素数
                    withAnimation(.linear(duration: duration).repeatForever(autoreverses: false)) {
                        scrollOffset = -(newWidth - containerWidth)
                    }
                } else {
                    // 文本较短时重置偏移
                    scrollOffset = 0
                }
            }
    }
    .frame(width: containerWidth, height: 18, alignment: .leading)
    .background(.red)
    
    Text(album.name)
        .font(.system(size: 9))
        .foregroundColor(.gray)
}

关键优化点:

  • 尺寸计算:通过GeometryReader和自定义PreferenceKey获取文本的实际宽度,对比容器宽度判断是否需要跑马灯
  • 精准偏移:动画偏移量设置为-(文本宽度 - 容器宽度),确保文本刚好完全移出容器右侧时完成一次动画循环
  • 自适应触发:只有当文本宽度超过容器宽度时才启动动画,短文本保持正常显示
  • 速度控制:通过文本宽度/30动态计算动画时长,保证不同长度的文本滚动速度一致

内容的提问来源于stack exchange,提问作者AdamLeet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 20:01:07