【问题标题】:Set up NSLayoutConstraint constant based on a view's height or screen height根据视图的高度或屏幕高度设置 NSLayoutConstraint 常量
【发布时间】: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 代码吗?

标签: ios swift autolayout nslayoutconstraint


【解决方案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】:

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

    我愿意:

    1. 为你的 NSLayoutConstraint 创建一个变量属性
    2. 在 viewDidLoad 中,使用该函数对其进行初始化:

      • (实例类型)constraintWithItem:(id)view1 属性:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation) 关系 toItem:(id)view2 属性:(NSLayoutAttribute)attr2 乘数:(CGFloat)乘数 常量:(CGFloat)c
    3. 使用 self.view.addConstraint 将约束添加到视图

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-18
      • 2020-09-04
      • 1970-01-01
      相关资源
      最近更新 更多