为什么 UIStackView 会一直折叠标签?
Why does UIStackView keep collapsing label?
我在水平堆栈视图中嵌入了一个标签和一个按钮 - 一个温度标签和一个 °C/°F 按钮(以粗体突出显示用户偏好;当他们点击按钮时,偏好开关和温度标签更新)。
°C 为粗体时没问题,但当我更改首选项且 °F 变为粗体时,按钮会折叠成仅显示 °...°F。 stack view 被分发给 Fill。我认为标签的水平内容压缩阻力优先级应该更高以防止它折叠,但这并没有改变任何东西(我尝试将其设置为 759)所以我不知道该做什么 search/change纠正这个问题。
有人能提醒我可能发生的事情吗?
非常感谢!
编辑: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
}
}
你可以这样做
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)
使用:
titleLabel?.attributedText = attributedString(from: title, boldRange: range)
不让 UIKit 和 auto-layout 完全处理更改。试试用这个代替:
setAttributedTitle(attributedString(from: title, boldRange: range), for: .normal)
应该解决这个问题。如果您仍然看到问题,请添加 .sizeToFit()
:
setAttributedTitle(attributedString(from: title, boldRange: range), for: .normal)
sizeToFit()
我在水平堆栈视图中嵌入了一个标签和一个按钮 - 一个温度标签和一个 °C/°F 按钮(以粗体突出显示用户偏好;当他们点击按钮时,偏好开关和温度标签更新)。
°C 为粗体时没问题,但当我更改首选项且 °F 变为粗体时,按钮会折叠成仅显示 °...°F。 stack view 被分发给 Fill。我认为标签的水平内容压缩阻力优先级应该更高以防止它折叠,但这并没有改变任何东西(我尝试将其设置为 759)所以我不知道该做什么 search/change纠正这个问题。
有人能提醒我可能发生的事情吗?
非常感谢!
编辑: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
}
}
你可以这样做
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)
使用:
titleLabel?.attributedText = attributedString(from: title, boldRange: range)
不让 UIKit 和 auto-layout 完全处理更改。试试用这个代替:
setAttributedTitle(attributedString(from: title, boldRange: range), for: .normal)
应该解决这个问题。如果您仍然看到问题,请添加 .sizeToFit()
:
setAttributedTitle(attributedString(from: title, boldRange: range), for: .normal)
sizeToFit()