自定义堆栈视图对齐

问题描述 投票:0回答:1

enter image description here

enter image description here

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"]]

样本数据

swift uikit uistackview
1个回答
0
投票

您只需要一个水平堆栈视图,但您的代码将创建 3 个。由于

self
已经是堆栈视图,因此
self
应该是唯一的水平堆栈视图。这是你的课程的重做:

final class CountDownStackView: UIStackView {
    func configure(withData data: [[String]]) {
        axis = .horizontal
        distribution = .equalSpacing
        alignment = .center
        spacing = 5

        for (column, rowData) in data.enumerated() {
            var labels = [UILabel]()
            for (row, text) in rowData.enumerated() {
                let label = UILabel(frame: .zero)
                label.font = row == 0 ? .preferredFont(forTextStyle: .title1) : .preferredFont(forTextStyle: .body)
                label.textColor = column + 1 == data.count ? .systemGray : .label
                label.text = text
                label.textAlignment = .left
                labels.append(label)
            }
            let verticalStackView = UIStackView(arrangedSubviews: labels)
            verticalStackView.axis = .vertical
            verticalStackView.distribution = .equalSpacing
            verticalStackView.alignment = .leading
            verticalStackView.spacing = 4

            addArrangedSubview(verticalStackView)

            if column + 1 < data.count {
                let parser = UILabel()
                parser.text = ":"
                parser.customizeLabel(font: UIFont.systemFont(ofSize: 18), textColor: .label)
                parser.sizeToFit()
                addArrangedSubview(parser)
            }
        }
    }
}

然后用类似的方式调用它:

let data: [[String]] = [
    ["02", "Hour"],
    ["43", "Minute"],
    ["23", "Second"],
]

let stack = CountDownStackView()
stack.configure(withData: data)

这为您提供了一个更接近第二张图片的布局。但这两个冒号看起来不对。我会将冒号作为字符串添加到您的

data
数组中。更新类如下:

final class CountDownStackView: UIStackView {
    func configure(withData data: [[String]]) {
        axis = .horizontal
        distribution = .equalSpacing
        alignment = .center
        spacing = 5

        for (column, rowData) in data.enumerated() {
            var labels = [UILabel]()
            for (row, text) in rowData.enumerated() {
                let label = UILabel(frame: .zero)
                label.font = row == 0 ? .preferredFont(forTextStyle: .title1) : .preferredFont(forTextStyle: .body)
                label.textColor = column + 1 == data.count ? .systemGray : .label
                label.text = text
                label.textAlignment = .left
                labels.append(label)
            }
            let verticalStackView = UIStackView(arrangedSubviews: labels)
            verticalStackView.axis = .vertical
            verticalStackView.distribution = .equalSpacing
            verticalStackView.alignment = .leading
            verticalStackView.spacing = 4

            addArrangedSubview(verticalStackView)
        }
    }
}

然后创建如下:

let data: [[String]] = [
    ["02", "Hour"],
    [":", " "],
    ["43", "Minute"],
    [":", " "],
    ["23", "Second"],
]

let stack = CountDownStackView()
stack.configure(withData: data)

这可以提供更好的布局效果。

虽然这个答案为您提供了自定义堆栈视图子类的布局问题的解决方案,但我建议整个方法对于实现某种倒计时视图来说远非理想。您当前的

CountDownStackView
使得在计时器倒计时时更新任何标签变得非常困难。

虽然我将保留另一个问题的详细信息(因为这超出了您原来问题的范围),但您确实应该创建

UIView
的子类,它使用标签的堆栈视图。它还应该使用可用于更新堆栈视图中的标签的
Timer

© www.soinside.com 2019 - 2024. All rights reserved.