如果子视图是使用 UIButton.Configuration 创建的 UIButton,则 UIStackView 没有正确的 .fill 分布。
在下面的示例中,我创建了两个带有 UIButton 类型子视图的 UIStackView。 两个stackview是相同的,但是子视图UIButtons的创建方式不同
let stackView1 = UIStackView()
stackView1.translatesAutoresizingMaskIntoConstraints = false
stackView1.distribution = .fill
如果 UIButton 是使用常规构造函数创建的,
let button = UIButton()
.fill 分布按预期工作(查看附图中的顶部堆栈视图)
如果 UIButtons 是通过将配置传递给构造函数来创建的
var configuration = UIButton.Configuration.plain()
let button = UIButton(configuration: configuration)
父 UIStackView 未提供正确的 fill 分布(附图中的底部堆栈视图)。
如何让 UIStackView 为使用 Configuration 创建的 UIButton 提供正确的分布?
环境:XCode 15.4,模拟器 iOS 17.5
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let stackView1 = UIStackView()
stackView1.translatesAutoresizingMaskIntoConstraints = false
stackView1.distribution = .fill
stackView1.alignment = .fill
let stackView2 = UIStackView()
stackView2.translatesAutoresizingMaskIntoConstraints = false
stackView2.distribution = .fill
stackView2.alignment = .fill
view.addSubview(stackView1)
view.centerXAnchor.constraint(equalTo: stackView1.centerXAnchor).isActive = true
view.centerYAnchor.constraint(equalTo: stackView1.centerYAnchor).isActive = true
view.addSubview(stackView2)
view.centerXAnchor.constraint(equalTo: stackView2.centerXAnchor).isActive = true
stackView2.topAnchor.constraint(equalTo: stackView1.bottomAnchor, constant: 40).isActive = true
stackView1.addArrangedSubview(makeButton("Button", backgroundColor: .red))
stackView1.addArrangedSubview(makeButton("Button Very Wild!!", backgroundColor: .blue))
stackView1.addArrangedSubview(makeButton("Button mid size", backgroundColor: .yellow))
stackView1.addArrangedSubview(makeButton("But", backgroundColor: .cyan))
stackView2.addArrangedSubview(makeButtonWithConfiguration("Button", backgroundColor: .red))
stackView2.addArrangedSubview(makeButtonWithConfiguration("Button Very Wild!!", backgroundColor: .blue))
stackView2.addArrangedSubview(makeButtonWithConfiguration("Button mid size", backgroundColor: .yellow))
stackView2.addArrangedSubview(makeButtonWithConfiguration("But", backgroundColor: .cyan))
}
func makeButton(_ title: String, backgroundColor: UIColor) -> UIButton {
let button = UIButton()
button.setTitle(title, for: .normal)
button.backgroundColor = backgroundColor
return button
}
func makeButtonWithConfiguration(_ title: String, backgroundColor: UIColor) -> UIButton {
var configuration = UIButton.Configuration.plain()
let button = UIButton(configuration: configuration)
button.setTitle(title, for: .normal)
button.backgroundColor = backgroundColor
return button
}
}
默认的
UIButton.Configuration.titleLineBreakMode
是.byWordWrapping
,这意味着与没有使用UIButton
创建的Configuration
不同,标题可以是多行。
可以将其设置为
.byClipping
,这样标题就只有一行。因此,按钮有一个“自然尺寸”。
var configuration = UIButton.Configuration.plain()
configuration.titleLineBreakMode = .byClipping
// you can also remove these insets and set the font size
// if you want it to look exactly like the buttons without a configuration
configuration.contentInsets.leading = 0
configuration.contentInsets.trailing = 0
configuration.titleTextAttributesTransformer = .init {
var new = $0
new.font = UIFont.systemFont(ofSize: 18)
return new
}