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

Custom Stack View对齐异常:代码效果与预期不符,求排查修正

倒计时StackView样式修正方案

问题说明

现有基于TinyConstraints的CountDownStackView代码,传入指定二维数组数据后,当前显示效果不符合预期,需要调整代码实现目标样式。

原代码

import UIKit
import TinyConstraints

final class CountDownStackView: UIStackView {
    func configure(withData data: [[String]]) {
           data.forEach { rowData in
               let verticalStackView = UIStackView()
               verticalStackView.axis = .vertical
               verticalStackView.spacing = 8
               
               rowData.forEach { text in
                   let label = UILabel()
                   label.text = text
                   label.backgroundColor = .lightGray
                   label.textAlignment = .center
                   verticalStackView.addArrangedSubview(label)
               }
               
               let horizontalStackView = UIStackView()
               horizontalStackView.axis = .horizontal
               horizontalStackView.spacing = 5
               
               horizontalStackView.addArrangedSubview(verticalStackView)
               
               let parser = UILabel()
               parser.text = ":"
               parser.customizeLabel(font: UIFont.systemFont(ofSize: 18),textColor: .white)
               horizontalStackView.addArrangedSubview(parser)
               
               addArrangedSubview(horizontalStackView)
           }
       }
    }

示例数据

let data: [[String]] = [
    ["02", " Hour"],
    ["43","minute"],
    ["23","second"]
]

问题排查

  1. 主StackView方向错误:CountDownStackView继承自UIStackView,默认布局方向为垂直(.vertical),但倒计时通常需要横向排列,导致当前元素垂直堆叠。
  2. 冒号添加逻辑错误:为每个时间单元单独包裹横向StackView并添加冒号,导致每个单元后都带冒号,不符合常规倒计时样式(仅单元间显示冒号)。
  3. 缺少必要的布局约束:时间数字Label未设置固定尺寸,可能导致显示大小不一致。

修正后的代码

import UIKit
import TinyConstraints

final class CountDownStackView: UIStackView {
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    private func commonInit() {
        // 设置主StackView为横向排列,配置间距与对齐方式
        axis = .horizontal
        spacing = 12
        alignment = .center
    }
    
    func configure(withData data: [[String]]) {
        // 清空已有子视图,避免重复调用时视图叠加
        arrangedSubviews.forEach { $0.removeFromSuperview() }
        
        data.enumerated().forEach { index, rowData in
            // 创建单个时间单元的垂直StackView(数字+单位)
            let verticalStackView = UIStackView()
            verticalStackView.axis = .vertical
            verticalStackView.spacing = 4
            verticalStackView.alignment = .center
            
            rowData.enumerated().forEach { textIndex, text in
                let label = UILabel()
                label.text = text
                label.backgroundColor = .lightGray
                label.textAlignment = .center
                
                // 为数字Label设置固定尺寸,保证显示统一;区分数字与单位的字体样式
                if textIndex == 0 {
                    label.width(40)
                    label.height(40)
                    label.font = .systemFont(ofSize: 20, weight: .bold)
                } else {
                    label.font = .systemFont(ofSize: 12)
                }
                
                verticalStackView.addArrangedSubview(label)
            }
            
            // 将时间单元添加到主StackView
            addArrangedSubview(verticalStackView)
            
            // 仅在非最后一个单元后添加冒号
            if index != data.count - 1 {
                let colonLabel = UILabel()
                colonLabel.text = ":"
                colonLabel.font = .systemFont(ofSize: 18, weight: .bold)
                colonLabel.textColor = .white
                addArrangedSubview(colonLabel)
            }
        }
    }
}

关键修改点

  • 新增commonInit方法,初始化主StackView为横向布局,配置合理的间距与对齐方式。
  • 通过enumerated遍历数据获取索引,仅在非最后一个时间单元后添加冒号,符合常规倒计时样式。
  • 为数字Label设置固定宽高,保证每个时间块尺寸统一,同时区分数字和单位的字体样式。
  • 配置前清空已有子视图,避免重复调用configure时出现视图叠加问题。

内容的提问来源于stack exchange,提问作者Murat Can Çiçek

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:47:51