【问题标题】:Divide the space for two views depending on Percentage根据百分比划分两个视图的空间
【发布时间】:2020-09-06 21:04:27
【问题描述】:

所以我有一个看法:

我在堆栈视图中有两个视图,使用情节提要。

我在 viewController 中得到了两个值,我希望每个视图大小对应于它们代表它们之和的百分比。

ex:stackview 的大小是 100,如果我得到 700 和 300,则视图大小将是 70 和 30

谢谢

【问题讨论】:

  • @rbaldwin 是的,我愿意
  • @rbaldwin 使用情节提要
  • @rbaldwin 不,我得到了两个值,例如 2500 和 3600,我必须相对于我得到的值来调整两个视图的大小。就像如果整个堆栈视图是 100%,然后两个累积将是整个堆栈视图
  • 您能否更新您的问题,澄清一下。
  • 当然。如果你能给我一些帮助就太好了

标签: ios swift dynamic uiview autolayout


【解决方案1】:

在故事板中:

  • 将两个视图放在一个堆栈视图中
  • 将堆栈视图设置为
    • 轴:垂直
    • 对齐:填充
    • 分布:填充
    • 间距:0(或任何您想要的间距)
  • 给出堆栈视图:
    • 顶部/底部/前导/尾随约束
    • 或宽度、高度和位置限制
  • 按住 Ctrl 键从底部视图拖动到顶部视图
  • 选择等高,乘数为 1(没关系,因为它会在代码中更改)

在您的视图控制器中,为该约束创建一个@IBOutlet,例如:

@IBOutlet var proportionalHeightConstraint: NSLayoutConstraint!

它在 Storyboard 中的外观如下:

我们无法直接更改乘数,因此请将此扩展添加到您的项目中:

extension NSLayoutConstraint {

    static func setMultiplier(_ multiplier: CGFloat, of constraint: inout NSLayoutConstraint) {
        NSLayoutConstraint.deactivate([constraint])

        let newConstraint = NSLayoutConstraint(item: constraint.firstItem as Any, attribute: constraint.firstAttribute, relatedBy: constraint.relation, toItem: constraint.secondItem, attribute: constraint.secondAttribute, multiplier: multiplier, constant: constraint.constant)

        newConstraint.priority = constraint.priority
        newConstraint.shouldBeArchived = constraint.shouldBeArchived
        newConstraint.identifier = constraint.identifier

        NSLayoutConstraint.activate([newConstraint])
        constraint = newConstraint
    }

}

viewDidLoad()(或者当你得到你的两个值时):

class CubiaxViewController: UIViewController {

    @IBOutlet var proportionalHeightConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()

        let top: CGFloat = 3600
        let bottom: CGFloat = 2500

        NSLayoutConstraint.setMultiplier(bottom / top, of: &proportionalHeightConstraint)

    }

}

这是它在运行时的样子:

    let top: CGFloat = 3600
    let bottom: CGFloat = 2500

它的外观如下:

    let top: CGFloat = 700
    let bottom: CGFloat = 300

它的外观如下:

    let top: CGFloat = 200
    let bottom: CGFloat = 1500

【讨论】:

    【解决方案2】:

    这些视图是 UIStackView 吗?如果是这样,你只需要限制他们的高度。

    制作view1.height = *multiplier* x view2.height

    您可以轻松计算出百分比的乘数,如multiplier = percentage2 / percentage1

    所以在你的例子中multiplier = 50 / 50 = 1。如果你愿意,比如说,30%/70% 的人可以使用multiplier = 70 / 30 = 2.333

    【讨论】:

    • 我不明白,假设topView值为201600,bottom view = 50400。你具体写什么。因为它不起作用,我不知道问题出在哪里。另外问题是您已经像 topView.frame.size.height 那样访问它,并且乘数不起作用,除非它是一个 CGPoint
    【解决方案3】:
    1. 将您的两个UIViews 放入您的UIStackView(垂直轴)
    2. 为您的 UIStackView 创建一个IBOutlet
    3. 为您的顶级UIView 创建一个IBOutlet
    4. 在 Storyboard 中将 UIStackView 分发设置为 fillEqually 以使警告静音。
    5. 在您的代码中计算顶视图的比例
    6. UIStackView 分布设置为填充
    7. 设置顶视图相对于UIStackView的高度乘数

    代码:

    class ViewController: UIViewController {
    
        @IBOutlet var stackView: UIStackView!
        @IBOutlet var topView: UIView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            let topHeight: CGFloat = 700.0
            let bottomHeight: CGFloat = 300.0
    
            let topViewRatio = topHeight / (topHeight + bottomHeight)
    
            stackView.distribution = .fill
            topView.heightAnchor.constraint(equalTo: stackView.heightAnchor, multiplier: topViewRatio).isActive = true
        }
    }
    

    【讨论】: