[英]adding leading / top constraints programmatically
我有以下代碼適用於高度和寬度約束。 嘗試添加前導約束和頂部約束時它會崩潰。 我還有其他具有高度、寬度、前導、頂部約束的按鈕組,但它們都設置在故事板上,所以我認為這些是我必須添加到每個按鈕的僅有的 4 個約束。
我有 7 個按鈕,每個按鈕用於一周中的一天。 當我添加代碼來執行前導和頂部約束時,它會因下面的錯誤代碼而中斷。 它僅適用於高度/寬度。 我猜這與我添加子視圖的方式或按鈕與視圖控制器的關系有關,或者在以編程方式執行時,我需要的約束超過我一直使用的 4 個約束(前導、頂部、寬度、高度)在故事板上。
func setupWeekdayButtons() {
self.weeklyButtons = [self.mondayButton, self.tuesdayButton, self.wednesdayButton, self.thursdayButton, self.fridayButton, self.saturdayButton, self.sundayButton]
for i in 0...6 {
print(i)
self.weeklyButtons[i].translatesAutoresizingMaskIntoConstraints = false
self.weeklyButtons[i].setTitle(self.weekdayLabels[i], for: .normal)
self.weeklyButtons[i].layer.borderColor = UIColor.black.cgColor
self.weeklyButtons[i].titleLabel?.textAlignment = .center
self.weeklyButtons[i].layer.borderWidth = 1.0
self.weeklyButtons[i].layer.cornerRadius = 6.0
self.weeklyButtons[i].setTitleColor(.black, for: .normal)
self.weeklyButtons[i].setTitleColor(.red, for: .selected)
self.weeklyButtons[i].addTarget(self, action: #selector(selectedDailyButton), for: .touchUpInside)
self.view.addSubview(self.weeklyButtons[i])
let heightConstraint = NSLayoutConstraint(
item: self.weeklyButtons[i],
attribute: NSLayoutConstraint.Attribute.height,
relatedBy: NSLayoutConstraint.Relation.equal,
toItem: nil,
attribute: NSLayoutConstraint.Attribute.notAnAttribute,
multiplier: 1.0,
constant: 30
)
let widthConstraint = NSLayoutConstraint(
item: self.weeklyButtons[i],
attribute: NSLayoutConstraint.Attribute.width,
relatedBy: NSLayoutConstraint.Relation.equal,
toItem: nil,
attribute: NSLayoutConstraint.Attribute.notAnAttribute,
multiplier: 1.0,
constant: 30
)
let leadingConstraint = NSLayoutConstraint(
item: self.weeklyButtons[i],
attribute: NSLayoutConstraint.Attribute.leading,
relatedBy: NSLayoutConstraint.Relation.equal,
toItem: self.view,
attribute: NSLayoutConstraint.Attribute.leading,
multiplier: 1.0,
constant: 100
)
let topConstraint = NSLayoutConstraint(
item: self.weeklyButtons[i],
attribute: NSLayoutConstraint.Attribute.top,
relatedBy: NSLayoutConstraint.Relation.equal,
toItem: self.view,
attribute: NSLayoutConstraint.Attribute.top,
multiplier: 1.0,
constant: 100
)
self.weeklyButtons[i].addConstraint(heightConstraint)
self.weeklyButtons[i].addConstraint(widthConstraint)
self.weeklyButtons[i].addConstraint(leadingConstraint)
self.weeklyButtons[i].addConstraint(topConstraint)
}
}
2019-03-07 14:38:59.176638-0500 Daily[27852:1408014] [LayoutConstraints] 未為約束准備視圖層次結構:添加到視圖時,約束的項必須是該視圖(或視圖)的后代本身)。 如果在組裝視圖層次結構之前需要解決約束,這將崩潰。 中斷 -[UIView(UIConstraintBasedLayout) _viewHierarchyUnpreparedForConstraint:] 進行調試。
2019-03-07 14:38:59.177816-0500 Daily[27852:1408014] [LayoutConstraints] 視圖層次結構沒有准備好約束。 約束:容器層次結構:> | > 在容器層次結構中找不到視圖: > 該視圖的超級視圖:NO SUPERVIEW
2019-03-07 14:38:59.192176-0500 Daily[27852:1408014] *** 由於未捕獲的異常“NSGenericException”而終止應用程序,原因:“無法在視圖上安裝約束。 約束是否引用了視圖子樹之外的內容? 那是非法的。 約束:視圖:>'
自從我在代碼中添加約束以來已經有一段時間了,但是如果沒有記錯,您必須在添加約束之前將視圖添加到視圖層次結構中。 (這就是錯誤消息所暗示的。)
self.weeklyButtons[i].addConstraint(leadingConstraint)
約束涉及weeklyButtons[i]
和self.view
。 如果使用addConstraint
激活約束,則必須將約束添加到兩個視圖的共同祖先。 這就是此錯誤消息告訴您的內容:
添加到視圖時,約束的項必須是該視圖(或視圖本身)的后代。
由於self.view
是weeklyButtons[i]
的weeklyButtons[i]
視圖,它算作兩個視圖的共同祖先。 因此,在這種情況下,您可以將約束添加到self.view
:
self.view.addConstraint(leadingConstraint)
但不要那樣做。 從 iOS 8 開始,你可以直接激活一個約束,UIKit 會自動將它添加到正確的視圖中:
leadingConstraint.isActive = true
但不要那樣做。 由於您要連續添加四個約束,因此像這樣同時激活四個約束可能會更有效:
NSLayoutConstraint.activate([
leadingConstraint,
topConstraint,
widthConstraint,
heightConstraint])
但不要那樣做。 從 iOS 9 開始,有一種更具可讀性的方式來創建約束:
NSLayoutConstraint.activate([
self.weeklyButtons[i].heightAnchor.constraint(equalToConstant: 30),
self.weeklyButtons[i].widthAnchor.constraint(equalToConstant: 30),
self.weeklyButtons[i].leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 100),
self.weeklyButtons[i].topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
])
但不要那樣做。 使用for
/ in
循環代替索引變量i
:
func setupWeekdayButtons() {
weeklyButtons = [mondayButton, tuesdayButton, wednesdayButton, thursdayButton, fridayButton, saturdayButton, sundayButton]
for (button, title) in zip(weeklyButtons, weekdayLabels) {
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle(title, for: .normal)
button.layer.borderColor = UIColor.black.cgColor
button.titleLabel?.textAlignment = .center
button.layer.borderWidth = 1.0
button.layer.cornerRadius = 6.0
button.setTitleColor(.black, for: .normal)
button.setTitleColor(.red, for: .selected)
button.addTarget(self, action: #selector(selectedDailyButton), for: .touchUpInside)
view.addSubview(button)
NSLayoutConstraint.activate([
button.heightAnchor.constraint(equalToConstant: 30),
button.widthAnchor.constraint(equalToConstant: 30),
button.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 100),
button.topAnchor.constraint(equalTo: view.topAnchor, constant: 100),
])
}
}
去做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.