2016-09-27 77 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指真正查看頂部,不考慮填充雙方狀態欄和的導航欄的高度增加。它們可以被替換爲常數,等待有人提出更優雅的解決方案。

相關問題