【问题标题】:Swift- unable to align stack elements with different font sizesSwift-无法对齐具有不同字体大小的堆栈元素
【发布时间】:2020-09-09 21:00:42
【问题描述】:

我有 2 个 UILabel 如下:

private lazy var titleLabel: UILabel = {
    let label = UILabel()
    label.textColor = Constants.mainFontColor.withAlphaComponent(0.7)
    label.translatesAutoresizingMaskIntoConstraints = false
    label.isUserInteractionEnabled = false
    label.sizeToFit()
    return label
}()

private lazy var valueLabel: UILabel = {
    let label = UILabel()
    label.textColor = Constants.mainFontColor
    label.translatesAutoresizingMaskIntoConstraints = false
    label.isUserInteractionEnabled = false
    label.sizeToFit()
    return label
}()

然后将这些标签放入 UIStackView:

private lazy var stackView: UIStackView = {
    let stack = UIStackView(arrangedSubviews: [titleLabel, valueLabel])
    stack.translatesAutoresizingMaskIntoConstraints = false
    stack.axis = .horizontal
    stack.spacing = 5
    stack.alignment = .firstBaseline
    addSubview(stack)
    return stack
}()

然后我创建了几个实例,例如:

private lazy var flightNumber: FuelSheetHeaderField = {
    return FuelSheetHeaderField(title: FuelSheetStringsField.flightNumber.title.localized,
                                value: viewModel.flightNumber, titleFontSize: 17, valueFontSize: 24)
}()

然后将它们放入单独的堆栈视图中:

   private lazy var flightData: UIStackView = {
        let stack = UIStackView(arrangedSubviews: [flightNumber, aircraftReg, dateTime, origin])
        stack.axis = .horizontal
        stack.distribution = .equalSpacing
        stack.spacing = Constants.standardHorizontalStackSpacing
        return stack
    }()

标题标签的字体大小为 12,值的字体大小为 17。除了一个自定义为相应的字体大小为 17 和 2 的标签。我试图让所有元素沿着同一基线对齐。我添加了以下约束:

titleLabel.firstBaselineAnchor.constraint(equalTo: valueLabel.firstBaselineAnchor),

但是效果如下:

大多数堆栈元素都是对齐的,但您可以看到第一个字体较大的元素比第二个元素高。这让我有点发疯。如何修复它,使堆栈中的所有元素沿同一基线对齐。

【问题讨论】:

    标签: swift uiview uistackview


    【解决方案1】:

    我认为您在尝试跨堆栈视图使用基线时会遇到麻烦。

    一个选项 - 不确定它是否适合你 - 是将所有标签放在一个水平堆栈视图中,并使用 .setCustomSpacing() 调整标签之间的空间。

    举个例子:

    Debug -> View Debugging -> Show View Frames:

    这是我用来生成的代码:

    class AlignedStackViewController: UIViewController {
    
        let detailsStack: UIStackView = {
            let v = UIStackView()
            v.axis = .vertical
            v.alignment = .leading
            v.distribution = .fill
            v.spacing = 12
            return v
        }()
        
        let dataStack: UIStackView = {
            let v = UIStackView()
            v.axis = .horizontal
            v.alignment = .firstBaseline
            v.distribution = .fill
            v.spacing = 5
            return v
        }()
        
        override func viewDidLoad() {
            super.viewDidLoad()
    
            view.backgroundColor = UIColor(red: 0.928, green: 0.973, blue: 1.0, alpha: 1.0)
    
            let fdLabel = UILabel()
            fdLabel.text = "FLIGHT DETAILS"
            
            detailsStack.addArrangedSubview(fdLabel)
            detailsStack.addArrangedSubview(dataStack)
            
            detailsStack.translatesAutoresizingMaskIntoConstraints = false
            
            view.addSubview(detailsStack)
            
            // respect safe area
            let g = view.safeAreaLayoutGuide
            
            NSLayoutConstraint.activate([
                // position stack view at 40, 100
                detailsStack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 40.0),
                detailsStack.topAnchor.constraint(equalTo: g.topAnchor, constant: 100.0),
            ])
            
            addLabelPair(with: "#", value: "VS0105", titleFontSize: 17, valueFontSize: 24)
            addLabelPair(with: "Reg:", value: "GAAAA", titleFontSize: 12, valueFontSize: 17)
            addLabelPair(with: "Departure:", value: "09 Sep 2020", titleFontSize: 12, valueFontSize: 17)
            addLabelPair(with: "at", value: "08:34", titleFontSize: 12, valueFontSize: 17)
    
            updateStackSpacing()
    
        }
        
        func updateStackSpacing() -> Void {
            // make sure stack has been filled
            guard dataStack.arrangedSubviews.count == 8 else {
                return
            }
            // verbose for clarity
            let flightNumberLabel = dataStack.arrangedSubviews[1]
            let aircraftRegLabel = dataStack.arrangedSubviews[3]
            dataStack.setCustomSpacing(12, after: flightNumberLabel)
            dataStack.setCustomSpacing(12, after: aircraftRegLabel)
        }
        
        func addLabelPair(with title: String, value: String, titleFontSize: CGFloat, valueFontSize: CGFloat) -> Void {
            
            let tLabel = UILabel()
            let vLabel = UILabel()
            
            tLabel.font = UIFont.systemFont(ofSize: titleFontSize)
            vLabel.font = UIFont.systemFont(ofSize: valueFontSize)
            
            tLabel.textColor = UIColor.black.withAlphaComponent(0.7)
            vLabel.textColor = UIColor.black
    
            tLabel.text = title
            vLabel.text = value
            
            dataStack.addArrangedSubview(tLabel)
            dataStack.addArrangedSubview(vLabel)
            
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      我认为,uiLabel 似乎有默认填充

      而默认的填充值取决于字体大小。

      尽管sizeToFit,结果是一样的

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-24
        • 2013-06-17
        • 1970-01-01
        相关资源
        最近更新 更多