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

Swift新手求助:实现格式对齐的收据打印(修复字符串长度变化导致的对齐失效问题)

解决Swift收据打印的三列对齐问题

看起来你遇到了固定宽度填充导致的对齐失效问题——当左侧名称长度变化时,原来的填充逻辑没办法维持三列的整齐布局。咱们来调整一下代码,实现像目标收据那样的左对齐序号、左对齐服务名称、右对齐金额的效果,同时支持自适应列宽,确保不管内容长短都能对齐。

问题根源分析

你当前的formattedString函数把金额和序号用同一个填充逻辑处理,没有明确划分列的宽度和对齐方式,一旦左侧名称长度超过设定的width,后续的空格填充就会混乱,自然没法保持对齐。

解决方案:分列控制对齐与宽度

我们可以重新设计格式化函数,明确划分三列的职责:

  1. 序号列:固定宽度,左对齐
  2. 服务名称列:可自适应最大宽度,左对齐
  3. 金额列:固定宽度,右对齐

同时要注意:打印收据必须使用等宽字体(比如Courier New),否则即使字符串长度一致,非等宽字体的字符宽度不同,对齐效果还是会失效。

改进后的代码示例

// 格式化单行收据内容
func formattedReceiptLine(serialNumber: String, serviceName: String, amount: String,
                          serialColumnWidth: Int = 3, amountColumnWidth: Int = 8) -> String {
    // 序号左对齐,填充到指定宽度
    let paddedSerial = serialNumber.padding(toLength: serialColumnWidth, withPad: " ", startingAt: 0)
    // 服务名称暂不固定宽度,后续统一计算最大宽度
    let paddedName = serviceName
    // 金额右对齐:在前面填充空格,确保总长度等于金额列宽度
    let paddedAmount = String(repeating: " ", count: max(0, amountColumnWidth - amount.count)) + amount
    
    return paddedSerial + paddedName + paddedAmount
}

// 生成完整收据内容
func generateReceipt(items: [(serial: String, name: String, amount: String)]) -> String {
    // 计算服务名称的最大长度,加2作为列宽(预留空格间距)
    let maxNameLength = items.map { $0.name.count }.max() ?? 0
    let nameColumnWidth = maxNameLength + 2
    
    // 格式化每一行,并统一调整名称列的宽度
    let formattedLines = items.map { item in
        let paddedName = item.name.padding(toLength: nameColumnWidth, withPad: " ", startingAt: 0)
        return item.serial.padding(toLength: 3, withPad: " ", startingAt: 0) + paddedName + String(repeating: " ", count: max(0, 8 - item.amount.count)) + item.amount
    }
    
    return formattedLines.joined(separator: "\n")
}

// 使用示例
let receiptItems = [
    ("1", "MAXIS Hotlink", "25.00"),
    ("0", "DIGI Prepaid", "5.00"),
    ("2", "CELCOM Xpax", "5.00"),
    ("3", "U Mobile Postpaid Plus", "45.90") // 测试长名称
]

let receipt = generateReceipt(items: receiptItems)
print(receipt)

代码说明

  1. 分列处理:每一列都有独立的对齐逻辑,序号和名称左对齐填充,金额右对齐填充,确保每列的边界清晰。
  2. 自适应列宽:generateReceipt函数会自动计算所有服务名称的最大长度,动态调整名称列的宽度,避免短名称浪费空间、长名称溢出的问题。
  3. 等宽字体要求:打印时务必设置打印机字体为等宽字体,比如UIFont(name: "CourierNewPSMT", size: 12),这是保证对齐效果的关键。

这样调整后,不管你的服务名称长短如何,三列内容都会整齐对齐,和目标收据的效果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 05:53:11