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

三个UIView等宽并排占满屏,移除一个后剩余两视图占满屏实现方案

解决动态调整UIView宽度的几种方案

这问题我之前做类似自适应布局时刚好碰到过,给你几个实用的方案,从最省心的开始说:

方案一:用UIStackView(最推荐)

这绝对是苹果官方最推荐的实现方式,完全不用手动管理约束变更,StackView会帮你搞定一切。

步骤很简单:

  • 把三个UIView放进一个水平方向的UIStackView里
  • 给StackView设置和父视图的约束:leading、trailing、top(或你需要的顶部约束)、bottom(或底部约束),让它完全占满屏幕宽度方向的空间
  • 设置StackView的两个关键属性:
    • distribution设为.fillEqually:让所有子视图均分可用空间
    • spacing设为0:确保子视图之间没有间隙

不管是用代码还是Storyboard/XIB都很方便:

代码实现示例:

// 创建三个子视图(假设你已经初始化了view1、view2、view3)
let stackView = UIStackView(arrangedSubviews: [view1, view2, view3])
stackView.axis = .horizontal
stackView.distribution = .fillEqually
stackView.spacing = 0

// 将StackView添加到父视图并设置约束
stackView.translatesAutoresizingMaskIntoConstraints = false
parentView.addSubview(stackView)
NSLayoutConstraint.activate([
    stackView.leadingAnchor.constraint(equalTo: parentView.leadingAnchor),
    stackView.trailingAnchor.constraint(equalTo: parentView.trailingAnchor),
    stackView.topAnchor.constraint(equalTo: parentView.topAnchor),
    stackView.bottomAnchor.constraint(equalTo: parentView.bottomAnchor)
])

移除视图时的操作:

只需要两步,StackView会自动调整剩余视图的宽度:

// 先从StackView的排列列表中移除
stackView.removeArrangedSubview(viewToRemove)
// 再从父视图中移除
viewToRemove.removeFromSuperview()
// 如果需要动画效果,包在动画块里就行
UIView.animate(withDuration: 0.3) {
    self.parentView.layoutIfNeeded()
}

方案二:手动管理Auto Layout约束(适合特殊场景)

如果你因为某些原因不想用StackView,那可以手动维护宽度约束的乘数。

核心思路是:

  1. 初始化时给每个视图的宽度约束设置为父视图宽度的1/3
  2. 移除一个视图后,把剩余两个视图的宽度约束乘数改成1/2

代码实现示例:

// 先保存每个视图的宽度约束引用,方便后续修改
private var view1WidthConstraint: NSLayoutConstraint!
private var view2WidthConstraint: NSLayoutConstraint!
private var view3WidthConstraint: NSLayoutConstraint!

// 初始化约束
func setupConstraints() {
    // 先给三个视图设置水平排列的约束(view1贴左,view2跟在view1后面,view3贴右)
    NSLayoutConstraint.activate([
        view1.leadingAnchor.constraint(equalTo: parentView.leadingAnchor),
        view2.leadingAnchor.constraint(equalTo: view1.trailingAnchor),
        view3.trailingAnchor.constraint(equalTo: parentView.trailingAnchor),
        // 垂直方向的约束根据你的需求设置,比如上下对齐父视图
        view1.topAnchor.constraint(equalTo: parentView.topAnchor),
        view1.bottomAnchor.constraint(equalTo: parentView.bottomAnchor),
        view2.topAnchor.constraint(equalTo: parentView.topAnchor),
        view2.bottomAnchor.constraint(equalTo: parentView.bottomAnchor),
        view3.topAnchor.constraint(equalTo: parentView.topAnchor),
        view3.bottomAnchor.constraint(equalTo: parentView.bottomAnchor)
    ])
    
    // 设置宽度约束,乘数为1/3
    view1WidthConstraint = view1.widthAnchor.constraint(equalTo: parentView.widthAnchor, multiplier: 1/3)
    view2WidthConstraint = view2.widthAnchor.constraint(equalTo: parentView.widthAnchor, multiplier: 1/3)
    view3WidthConstraint = view3.widthAnchor.constraint(equalTo: parentView.widthAnchor, multiplier: 1/3)
    
    NSLayoutConstraint.activate([view1WidthConstraint, view2WidthConstraint, view3WidthConstraint])
}

// 移除视图的方法
func removeView(_ viewToRemove: UIView) {
    viewToRemove.removeFromSuperview()
    
    // 根据移除的视图,更新剩余视图的宽度约束
    switch viewToRemove {
    case view1:
        view2WidthConstraint.isActive = false
        view3WidthConstraint.isActive = false
        view2WidthConstraint = view2.widthAnchor.constraint(equalTo: parentView.widthAnchor, multiplier: 1/2)
        view3WidthConstraint = view3.widthAnchor.constraint(equalTo: parentView.widthAnchor, multiplier: 1/2)
    case view2:
        view1WidthConstraint.isActive = false
        view3WidthConstraint.isActive = false
        view1WidthConstraint = view1.widthAnchor.constraint(equalTo: parentView.widthAnchor, multiplier: 1/2)
        view3WidthConstraint = view3.widthAnchor.constraint(equalTo: parentView.widthAnchor, multiplier: 1/2)
    case view3:
        view1WidthConstraint.isActive = false
        view2WidthConstraint.isActive = false
        view1WidthConstraint = view1.widthAnchor.constraint(equalTo: parentView.widthAnchor, multiplier: 1/2)
        view2WidthConstraint = view2.widthAnchor.constraint(equalTo: parentView.widthAnchor, multiplier: 1/2)
    default:
        break
    }
    
    // 激活新的约束并更新布局
    NSLayoutConstraint.activate([view1WidthConstraint, view2WidthConstraint, view3WidthConstraint].compactMap { $0 })
    UIView.animate(withDuration: 0.3) {
        self.parentView.layoutIfNeeded()
    }
}

总结

优先选择UIStackView方案,它的代码量少、逻辑简单,而且苹果已经帮我们处理了所有布局变更的细节,不容易出错。手动约束的方案适合一些特殊的定制化场景,但需要额外维护约束的状态,相对繁琐。

内容的提问来源于stack exchange,提问作者Videh Jaiswal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:35:29