根据视图的高度或屏幕高度设置 NSLayoutConstraint 常量

Posted

技术标签:

【中文标题】根据视图的高度或屏幕高度设置 NSLayoutConstraint 常量【英文标题】:Set up NSLayoutConstraint constant based on a view's height or screen height 【发布时间】:2014-11-16 04:50:33 【问题描述】:

我以编程方式创建了一个自动布局约束,它将标签从其父视图的底部向上移动 25 个点。我在这个场景中没有定义其他约束。 25 在大多数设备上都很好,但在 iPhone 4s 上太高了。对于该屏幕尺寸,我想让它从底部向上大约 15。但是后来我认为获得一个变量常量会好得多,而不是为所有屏幕尺寸强制执行一个固定值,或者尝试为一个特定的屏幕尺寸更改它。但是使用自动布局似乎不可能做到这一点。是吗?

我在想获得变量常量的一种方法是根据屏幕(或视图)高度计算一个值。例如,常数将等于self.view.frame.size.height / 30。在 iPhone 4(仅限纵向)上,它将是 16,iPhone 5 几乎是 19,等等。这将是完美的。或者另一种方式,高度的 3%。不过,这些值对于旋转来说需要是动态的,因为高度会发生变化。

是否可以使用基于某些计算或屏幕/视图高度具有可变常量的自动布局约束?或者是否有其他解决方案可以让我获得所需的行为 - 避免固定的自动布局常量?

这是一些示例代码,来自viewDidLoad

let footerLabel = UILabel()
footerLabel.text = "my text"
footerLabel.sizeToFit()
footerLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
self.view.addSubview(footerLabel)
self.view.addConstraint(NSLayoutConstraint(item: footerLabel, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 1, constant: -25))
self.view.addConstraint(NSLayoutConstraint(item: footerLabel, attribute: .CenterX, relatedBy: .Equal, toItem: self.view, attribute: .CenterX, multiplier: 1, constant: 0))

【问题讨论】:

当您说以编程方式时,您的意思是您在代码或 Storyboard 中创建了约束? @Spectravideo328 在代码中,在viewDidLoad 所以你不能使用:self.myConstraint.constant = myVariableDistanceValue; @Spectravideo328 好吧,我没有存储对约束的引用,在viewDidLoad 它不会知道视图的大小,并且必须在大小更改时更新(旋转) . 您能出示您的 viewDidLoad 代码吗? 【参考方案1】:

我在想获得变量常量的一种方法是 根据屏幕(或视图)高度计算一个值。例如, 常数将等于 self.view.frame.size.height / 30。开 iPhone 4(仅限纵向)它将是 16,iPhone 5 几乎是 19等。这将是完美的。或者另一种方式,高度的 3%。 但是,这些值对于旋转需要是动态的,因为 高度会改变。

您可以将您的第一个约束更改为:

self.view.addConstraint(NSLayoutConstraint(item: footerLabel, attribute: .Bottom, relatedBy: .Equal, toItem: self.view, attribute: .Bottom, multiplier: 0.97, constant: 1))

保持常数 0 并将乘数更改为 0.97 意味着标签底部将始终比视图底部高 3%。

【讨论】:

优秀的答案!你让我很开心,我很高兴我终于知道了乘数的作用!【参考方案2】:

您可以设置“间隔”视图,其高度限制为view 的 3%。

override func viewDidLoad() 
    super.viewDidLoad()

    let label = UILabel()
    let spacer = UIView()

    label.setTranslatesAutoresizingMaskIntoConstraints(false)
    spacer.setTranslatesAutoresizingMaskIntoConstraints(false)
    spacer.hidden = true

    view.addSubview(spacer)
    view.addSubview(label)
    var views = ["spacer":spacer, "label":label]
    view.addConstraint(NSLayoutConstraint(item: spacer, attribute: .Height, relatedBy: .Equal, toItem: view, attribute: .Height, multiplier: 0.03, constant: 0))
    view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:[label][spacer]|", options: nil, metrics: nil, views: views))

    view.addConstraint(NSLayoutConstraint(item: label, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1, constant: 0))

    label.backgroundColor = UIColor.purpleColor()
    label.text = "THIS IS MY LABEL"

【讨论】:

【参考方案3】:

我不会将约束直接分配给视图。

我愿意:

    为你的 NSLayoutConstraint 创建一个变量属性

    在 viewDidLoad 中,使用该函数对其进行初始化:

    (实例类型)constraintWithItem:(id)view1 属性:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation) 关系 toItem:(id)view2 属性:(NSLayoutAttribute)attr2 乘数:(CGFloat)乘数 常量:(CGFloat)c

    使用 self.view.addConstraint 将约束添加到视图

    当方向改变或基于设备时,为该约束分配不同的值(使用 .constant)。

【讨论】:

以上是关于根据视图的高度或屏幕高度设置 NSLayoutConstraint 常量的主要内容,如果未能解决你的问题,请参考以下文章

相应地设置自动布局约束

根据 iOS SWIFT 高度更高的 UIImageView 或 UILabel 设置 UITableViewCell 高度

如何将 UICollectionViewCell 高度设置为视图(屏幕)高度的 90%?

允许滚动视图的高度根据图像大小而改变

是否可以在运行时使用 AutoLayout 根据屏幕高度或屏幕宽度中的最大值来制作 1:1 的纵横比?

UITableview 高度根据单元格设置