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

SwiftUI动态岛紧凑模式:秒表运行时为何占满横向空间?

SwiftUI Dynamic Island紧凑模式秒表显示异常原因分析

在SwiftUI的Dynamic Island紧凑模式下运行秒表时,使用相同的字体与颜色配置,却出现显示差异:

  • 空闲状态下秒表显示正常(对应第一张截图)
  • 运行状态下Dynamic Island占满整个横向空间(对应第二张截图),预期应保持空闲状态的样式

问题代码片段

compactTrailing中的实现:

if stopwatch.isRunning {
  // Stopwatch running state
  Text(timerInterval: stopwatch.timeInterval, countsDown: false)
    .font(.system(size: 14, weight: .medium))
    .foregroundColor(iconTintDarkMode)
} else {
  // Stopwatch idle state
  Text(timerString(time: stopwatch.elapsedTime))
    .font(.system(size: 14, weight: .medium))
    .foregroundColor(iconTintDarkMode)
}

辅助方法timerString:

func timerString(time: Double) -> String {
  var result = ""
  let hours = Int(time) / 3600
  let minutes = Int(time) / 60 % 60
  let seconds = Int(time) % 60

  if hours > 0 {
    result.append(String(format: "%02d:", hours))
  }
  result.append(String(format: "%02d:%02d", minutes, seconds))
  return result
}

显示差异原因

两种状态用了不同的Text初始化方式,造成了不一样的布局表现:

  • 空闲状态:用Text(String)创建的视图,会根据字符串实际宽度自动调整大小,只占内容需要的横向空间,符合紧凑模式的预期。
  • 运行状态:Text(timerInterval:countsDown:)这个API生成的文本视图,默认会占满所有可用的横向空间。因为系统考虑到定时器文本宽度会随时间动态变化(比如从“00:00”变到“01:00”再到“10:00”),为了避免频繁调整布局,默认给这个视图开了“最大宽度权限”,导致它撑满了Dynamic Island的横向空间。

修复方案

给运行状态的Text加上.fixedSize()修饰符,强制它根据当前显示的定时器文本宽度来布局,不再占满全部空间:

if stopwatch.isRunning {
  Text(timerInterval: stopwatch.timeInterval, countsDown: false)
    .font(.system(size: 14, weight: .medium))
    .foregroundColor(iconTintDarkMode)
    .fixedSize() // 添加这行代码
} else {
  Text(timerString(time: stopwatch.elapsedTime))
    .font(.system(size: 14, weight: .medium))
    .foregroundColor(iconTintDarkMode)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:05:53