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

SwiftUI中如何独立格式化Measurement数值与单位并设置不同字体?

实现单位与数值独立设置样式的方法

在SwiftUI中直接使用Text(totalDistance, format: .measurement(...))无法单独为单位设置样式,不过可以通过拆分数值与单位的显示来实现需求,下面提供两种实用方案:

方案一:直接拆分数值与单位(简单快捷)

利用Measurement的value属性获取数值,unit.symbol获取单位符号,然后用HStack组合两个Text组件分别设置样式:

private let totalDistance = Measurement(value: 2.5, unit: UnitLength.kilometers)

var body: some View {
    VStack {
        HStack(alignment: .top, spacing: 2) {
            Text(String(format: "%.1f", totalDistance.value))
                .font(.title) // 数值设置大字体
            Text(totalDistance.unit.symbol)
                .font(.caption) // 单位设置caption样式
        }
        Text("TIME")
            .font(.subheadline)
            .foregroundColor(.secondary)
    }
}

如果需要适配不同地区的数字格式(比如部分地区用逗号表示小数点),可以替换成NumberFormatter来格式化数值:

private func formattedValue() -> String {
    let formatter = NumberFormatter()
    formatter.numberStyle = .decimal
    formatter.maximumFractionDigits = 1
    return formatter.string(from: NSNumber(value: totalDistance.value)) ?? ""
}

// 调用时:Text(formattedValue())

方案二:用MeasurementFormatter拆分(适配本地化)

如果需要严格遵循系统的本地化显示规则(比如不同语言下单位的排版逻辑),可以用MeasurementFormatter先拆分出数值和单位的字符串,再分别设置样式:

private let totalDistance = Measurement(value: 2.5, unit: UnitLength.kilometers)
private let measurementFormatter: MeasurementFormatter = {
    let formatter = MeasurementFormatter()
    formatter.unitOptions = .providedUnit
    formatter.numberFormatter.maximumFractionDigits = 1
    formatter.unitStyle = .narrow // 和你之前使用的.narrow格式保持一致
    return formatter
}()

private func splitMeasurement() -> (value: String, unit: String) {
    let formattedString = measurementFormatter.string(from: totalDistance)
    // 定位第一个非数字/小数点的位置,拆分数值与单位
    guard let splitIndex = formattedString.firstIndex(where: { !$0.isNumber && $0 != "." }) else {
        return (formattedString, "")
    }
    let valueString = String(formattedString[..<splitIndex])
    let unitString = String(formattedString[splitIndex...])
    return (valueString, unitString)
}

var body: some View {
    VStack {
        let (value, unit) = splitMeasurement()
        HStack(alignment: .top, spacing: 2) {
            Text(value)
                .font(.title)
            Text(unit)
                .font(.caption)
        }
        Text("TIME")
            .font(.subheadline)
            .foregroundColor(.secondary)
    }
}

两种方案都能实现你要的效果,方案一适合简单场景,方案二更适配多语言环境。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:17:33