2016-09-27 70 views
6

我从xib添加视图到我的ViewController中。然后我把它的约束真正适合它以编程方式在Swift中追踪和引导约束(NSLayoutConstraints)

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 
    ... 
    ... 
    view!.addSubview(gamePreview) 
    gamePreview.translatesAutoresizingMaskIntoConstraints = false 
    if #available(iOS 9.0, *) { 
     // Pin the leading edge of myView to the margin's leading edge 
     gamePreview.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true 
     //Pin the trailing edge of myView to the margin's trailing edge 
     gamePreview.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true 

    } else { 
     // Fallback on earlier versions 
     view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .TrailingMargin, relatedBy: .Equal, toItem: view, attribute: .TrailingMargin, multiplier: 1, constant: 0)) 

     view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .LeadingMargin, relatedBy: .Equal, toItem: view, attribute: .LeadingMargin, multiplier: 1, constant: 0)) 
    } 
    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0)) 
    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 131)) 
} 

我想要做的:要真正适合我的观点其约束到顶部,领先,落后于视图控制器的观点,并配有前缀的高度。我添加到主视图的视图具有自己的透明背景视图,因此不需要边距(视图意味着设备的宽度大小,所以)。

我已经放置了2对夫妇的线,应该是相等的(在我的尝试中),如果,因为前2行if实际上只在iOS9中可用,而我试图在else语句中为每个设备(从iOS 8开始)做同样的事情。

这就是我得到:

iOS9 +左,iOS8上+右。透明背景是红色显示会发生什么(在图像中的不同高度不介意的话,他们在应用相等的高度,而不是看在左侧加入利润率和右)

我也尝试AutoLayoutDSL-Swift,但没有帮助,我不是专家,但每一次尝试都只会让事情变得更糟。

如何使用经典的NSLayoutConstraints方法编写这些约束,以及如何使用AutoLayoutDSL或其分支等框架以更好的方式编写所有约束? (或替代方案,但现在大多我担心官方库)

+2

在你的iOS前9码你已经使用'leadingMargin'和'trailingMargin',所以你得到的利润。使用'前导'和'尾随' – Paulw11

+0

另外,,如果你做了这个改变,那么相同的代码将适用于所有版本,iOS 8和以上 – Paulw11

+0

工程!你还会介意告诉我如何使用AutoLayoutDSL-Swift作为顶部锚点,特别是导航栏...我尝试了'view => gamePreview.top == view.top',来完成我倒入倒数第二位约束,但视图在导航条下...这将帮助我将所有这些臃肿的代码减少到由4分割的行中。我尝试添加一个总和为'self.navigationController!.navigationBar.height'的偏移量,但它给出了一个编译错误,而它的工作原理是数字化(如30)。 – BlackBox

回答

13

您需要使用leadingtrailing属性,而不是leadingMargintrailingMargin属性:

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 
    ... 
    ... 
    view!.addSubview(gamePreview) 
    gamePreview.translatesAutoresizingMaskIntoConstraints = false 

    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Trailing, relatedBy: .Equal, toItem: view, attribute: .Trailing, multiplier: 1, constant: 0))    
    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1, constant: 0)) 

    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0)) 
    view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 131)) 
} 
+0

如何获得该视图的当前约束?你知道吗??我找不到任何好的解决方案 –

+0

你是什么意思的“那个看法”。通常情况下,如果您使用故事板,则在创建时将属性约束的引用存储在属性中,或者使用IBoutlet。 – Paulw11

+0

假设我不想要任何IBOutlet引用该视图的约束,并且存在返回数组的UIView.constraints的数组属性。如何获得领先,尾随,顶部等没有创建引用属性? –

2

猜对了感谢@ Paulw11 ......这是解决方案

view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Trailing, relatedBy: .Equal, toItem: view, attribute: .Trailing, multiplier: 1, constant: 0))  
view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Leading, relatedBy: .Equal, toItem: view, attribute: .Leading, multiplier: 1, constant: 0))   
view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Top, relatedBy: .Equal, toItem: self.topLayoutGuide, attribute: .Bottom, multiplier: 1, constant: 0)) 
view.addConstraint(NSLayoutConstraint(item: gamePreview, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute,multiplier: 1, constant: 131)) 

此外,我管理,因为它遵循使用重写一遍AutoLayoutDSL-Swift兴趣的人

view => gamePreview.trailing == view.trailing 
    => gamePreview.leading == view.leading 
    => gamePreview.height == 131 
    => gamePreview.top == view.top + self.navigationController!.navigationBar.bounds.height + UIApplication.sharedApplication().statusBarFrame.size.height 

最后一行是有点长,因为view.top指真正查看顶部,不考虑填充双方状态栏和的导航栏的高度增加。它们可以被替换为常数,等待有人提出更优雅的解决方案。

相关问题