为啥 UIStackView 不断折叠标签?

Posted

技术标签:

【中文标题】为啥 UIStackView 不断折叠标签?【英文标题】:Why does UIStackView keep collapsing label?为什么 UIStackView 不断折叠标签? 【发布时间】:2019-07-14 09:22:02 【问题描述】:

我在水平堆栈视图中嵌入了一个标签和一个按钮 - 一个温度标签和一个 °C/°F 按钮(以粗体突出显示用户偏好;当他们点击按钮时,偏好切换并温度标签更新)。

当°C 为粗体时很好,但是当我更改首选项并且°F 变为粗体时,按钮折叠为仅显示°...°F。堆栈视图分发给 Fill。我认为标签的水平内容压缩阻力优先级应该更高以防止它崩溃,但这并没有改变任何东西(我尝试将其设置为 759)所以我不知道要搜索/更改什么来纠正这个。

有没有人能告诉我可能发生的事情?

非常感谢!

编辑:UIStackView 中的标签和按钮之间没有其他约束。堆栈视图位于带有城市标签的垂直堆栈视图中 - 参见图片。 该垂直堆栈视图固定在屏幕的顶部和底部。

第二次编辑:按下按钮时,我执行以下操作:

@IBAction func updateTemperaturePreference(_ sender: TemperaturePreferenceButton) 
    temperaturePreference = (temperaturePreference == .celsius) ? .fahrenheit: .celsius

temperaturePreference 上有一个 didSet,所以当它改变时,它会在自定义按钮上调用 updateStyle:

   temperaturePreferenceButton.updateStyle(temperaturePreference: temperaturePreference)

这是我的自定义按钮的代码:

class TemperaturePreferenceButton: UIButton 

let title = UnitTemperature.celsius.symbol + "/" + UnitTemperature.fahrenheit.symbol + "Some more text"

override init(frame: CGRect) 
    super.init(frame: frame)
    setupButton()


required init?(coder aDecoder: NSCoder) 
    super.init(coder: aDecoder)
    setupButton()


private func setupButton() 
    setTitle(title, for: .normal)


func updateStyle(temperaturePreference: TemperaturePreference) 
        switch temperaturePreference 
        case .celsius:
            let range = NSRange(location: 0, length: 2)
            titleLabel?.attributedText = attributedString(from: title, boldRange: range)

        case .fahrenheit:
            let range = NSRange(location: 3, length: 2)
            titleLabel?.attributedText = attributedString(from: title, boldRange: range)
    
    setNeedsDisplay()


private func attributedString(from string: String, boldRange: NSRange?) -> NSAttributedString 
    let fontSize = UIFont.systemFontSize
    let attributes = [
        NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: fontSize),
        NSAttributedString.Key.backgroundColor: UIColor.blue
    ]
    let nonBoldAttributes = [
        NSAttributedString.Key.font: UIFont.systemFont(ofSize: fontSize),
        NSAttributedString.Key.backgroundColor: UIColor.red
    ]
    let attributedString = NSMutableAttributedString(string: string, attributes: nonBoldAttributes)
    if let range = boldRange 
        attributedString.setAttributes(attributes, range: range)
    
    return attributedString

【问题讨论】:

您能分享所有其他限制吗 抱歉迟到的回复 - 我现在添加了更多详细信息,但如果需要其他信息,请告诉我! @ADB - 显示您用于更改按钮标题的代码/ @DonMag 我已将此添加到问题中 - 非常感谢。 【参考方案1】:

使用:

titleLabel?.attributedText = attributedString(from: title, boldRange: range)

不让 UIKit 和自动布局完全处理更改。尝试改用这个:

setAttributedTitle(attributedString(from: title, boldRange: range), for: .normal)

应该解决这个问题。如果您仍然发现问题,请添加.sizeToFit()

setAttributedTitle(attributedString(from: title, boldRange: range), for: .normal)
sizeToFit()

【讨论】:

【参考方案2】:

你可以这样做

        let attrTitle = NSMutableAttributedString(string: "°C/°F")
        attrTitle.beginEditing()
        let range = toggle == true ? NSRange(location: 0, length: 2) : NSRange(location: 3, length: 2)
        attrTitle.addAttribute(NSAttributedString.Key.font,
                               value: UIFont.systemFont(ofSize: 14, weight: .bold),
                               range: range)
        attrTitle.endEditing()
        sender.setAttributedTitle(attrTitle, for: .normal)

【讨论】:

以上是关于为啥 UIStackView 不断折叠标签?的主要内容,如果未能解决你的问题,请参考以下文章

为啥父 UIStackView 无法识别子 StackView 的高度?

为啥图像视图会拉伸以填充 UIStackView 中宽度的一半?

根据屏幕高度更改 UIStackView 中项目的高度

为啥 UIStackView 调整排列的子视图的大小?

为啥 UIStackView 不堆叠 UILabel 安排的子视图?

为啥 UIStackView 中的 UILabel 在重用时会失去高度?