将NSLayoutConstraint视图设置为右上角

时间:2015-08-22 02:24:08

标签: ios swift uiscrollview autolayout

我最终想要解决这个问题。在CSS中,您可以执行以下操作:

img {
  position: absolute;
  width: 50px;
  height: 50px;
  top: 0;
  right: 0;
}

在Swift中,我使用编程接口来设置图像的布局约束。它看起来像这样:

let img = UIImageView(image: UIImage(named: "my-image"))
img.setTranslatesAutoresizingMaskIntoConstraints(false)
mainScrollView.addSubview(img)
mainScrollView.addConstraint(NSLayoutConstraint(item: img, attribute: .Width,    relatedBy: .Equal, toItem: nil,            attribute: .NotAnAttribute, multiplier: 1, constant: 50))
mainScrollView.addConstraint(NSLayoutConstraint(item: img, attribute: .Height,   relatedBy: .Equal, toItem: nil,            attribute: .NotAnAttribute, multiplier: 1, constant: 50))
mainScrollView.addConstraint(NSLayoutConstraint(item: img, attribute: .Top,      relatedBy: .Equal, toItem: mainScrollView, attribute: .Top,            multiplier: 1, constant: 0))
mainScrollView.addConstraint(NSLayoutConstraint(item: img, attribute: .Trailing, relatedBy: .Equal, toItem: mainScrollView, attribute: .Trailing,       multiplier: 1, constant: 0))

然而,由于某些奇怪的原因,它尊重宽度和高度布局约束,即使是最重要的约束。但它基本上在屏幕左侧50点。如果我将最后一个.Trailing常量设置为50,它实际上会将其移动到左上角的视图中(是的,我对此非常困惑)。

4 个答案:

答案 0 :(得分:2)

约束应该应用于视图,该视图是约束中涉及的视图的最近共同祖先。所以我可以在你发布的代码中看到两个错误:

  1. 如果您要设置视图的heightwidth,则视图本身是最近的共同祖先视图,因此应该直接对其应用约束。所以你的代码应该是:

    item.addConstraint(NSLayoutConstraint(item: img, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 50))
    item.addConstraint(NSLayoutConstraint(item: img, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 50))
    
  2. 由于此约束涉及的视图:

    NSLayoutConstraint(item: img, attribute: .Top, relatedBy: .Equal, toItem: mainView, attribute: .Top, multiplier: 1, constant: 0))
    

    是另一个的子视图,它应该应用于父视图:

    mainView.addConstraint(NSLayoutConstraint(item: img, attribute: .Top, relatedBy: .Equal, toItem: mainView, attribute: .Top, multiplier: 1, constant: 0)))
    
  3. 关于Trailing属性的问题,您应该考虑在添加约束时定义此公式:

    item1.attribute = item2.attribute + constant
    

    因此,如果要定义两个属性都为Trailing的约束,则应使用负常量将一个视图放在另一个视图中:

    --------------------------
    View1                    |
    -------------            |
    View2       |  - (-50) - |  
    

答案 1 :(得分:0)

您是否尝试过不涉及代码的方式?使用故事板视图右下角的按钮?

答案 2 :(得分:0)

你只想把它设置在右上方,宽度和高度都是50?也许你可以这样做:

let img = UIImageView(image: UIImage(named: "my-image"))
img.setTranslatesAutoresizingMaskIntoConstraints(false)
mainScrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:[img(50)]-0-|", options: NSLayoutFormatOptions(0), metrics: nil, views: ["img" : img]))
mainScrollView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-0-[img(50)]", options: NSLayoutFormatOptions(0), metrics: nil, views: ["img" : img]))

答案 3 :(得分:0)

问题在于,与标准视图不同,滚动视图与其子视图之间的约束不会决定子视图的大小,而是滚动视图的contentSize这可能看起来很好奇,但它实际上是一个很棒的功能,让我们无法手动计算contentSize。有关详细信息,请参阅Technical Note TN2154

但这意味着为了在滚动视图中指定子视图的大小,您实际上必须引用滚动视图的外部(例如视图控制器的主要{ {1}})。

所以你可以放一个"容器"在滚动视图内查看并将图像视图放在其右上角。然后,您可以将容器定义为主视图的宽度。这样你就可以完成两个目标,指定滚动视图内容的宽度,并在其中指定图像视图的位置:

view