You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用UIButton.Configuration创建按钮时UIStackView的.fill布局失效问题

UIStackView对Configuration创建的UIButton无法应用.fill布局的解决方法

问题描述

当子视图是通过UIButton.Configuration创建的UIButton时,UIStackView的.fill布局分布无法正常生效。

我们创建了两个配置完全一致的UIStackView,仅子视图UIButton的创建方式不同:

let stackView1 = UIStackView()
stackView1.translatesAutoresizingMaskIntoConstraints = false
stackView1.distribution = .fill
  • 使用常规构造器创建UIButton时,.fill布局可正常生效(对应附图中上方的栈视图):
    let button = UIButton()
    
  • 通过UIButton.Configuration构造器创建UIButton时,父UIStackView无法应用正确的.fill布局(对应附图中下方的栈视图):
    var configuration = UIButton.Configuration.plain()
    let button = UIButton(configuration: configuration)
    

完整测试代码:

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.filled()
    configuration.title = title
    configuration.baseBackgroundColor = backgroundColor
    let button = UIButton(configuration: configuration)
    return button
  }
}

布局对比示意图

环境:XCode 15.4,iOS 17.5模拟器


问题原因

通过UIButton.Configuration创建的按钮,默认带有较高的内容压缩抵抗优先级和内容拥抱优先级,这两个优先级会阻止UIStackView的.fill布局对按钮进行拉伸。而常规UIButton的这些优先级默认值较低,因此能被栈视图正常拉伸填充。


解决方法

方法1:调整按钮的优先级

在创建Configuration按钮后,手动修改其水平方向的优先级,允许栈视图对按钮进行拉伸和压缩:

func makeButtonWithConfiguration(_ title: String, backgroundColor: UIColor) -> UIButton {
    var configuration = UIButton.Configuration.filled()
    configuration.title = title
    configuration.baseBackgroundColor = backgroundColor
    let button = UIButton(configuration: configuration)
    // 降低水平内容压缩抵抗优先级,允许按钮被压缩
    button.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
    // 降低水平内容拥抱优先级,允许按钮被拉伸
    button.setContentHuggingPriority(.defaultLow, for: .horizontal)
    return button
}

方法2:清除Configuration的尺寸约束

直接通过Configuration的sizeConstraints属性移除按钮的固有尺寸约束,让栈视图完全控制按钮尺寸:

func makeButtonWithConfiguration(_ title: String, backgroundColor: UIColor) -> UIButton {
    var configuration = UIButton.Configuration.filled()
    configuration.title = title
    configuration.baseBackgroundColor = backgroundColor
    // 清除固有尺寸约束,交由栈视图管理尺寸
    configuration.sizeConstraints = nil
    let button = UIButton(configuration: configuration)
    return button
}

内容的提问来源于stack exchange,提问作者Petro Shm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 23:18:13