如果子视图是使用 UIButton.Configuration 创建的 UIButton,则 UIStackView 分布错误

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

如果子视图是使用 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
  }
}

Incorrect UIStackView disctribution

ios swift uikit uibutton uistackview
1个回答
0
投票

默认的

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
}
© www.soinside.com 2019 - 2024. All rights reserved.