2016-02-17 53 views
7

我在故事板編輯器中的UIViewController中添加了一個UILabel(amountLabel)。然後在swift文件viewDidLoad中,我編程創建一個UITextField(paymentTextField)並嘗試在amountLabelpaymentTextField之間添加一個約束。這是我在viewDidload代碼:以編程方式快速添加約束

let paymentTextField = UITextField() 
    paymentTextField.translatesAutoresizingMaskIntoConstraints = false 
    paymentTextField.frame = CGRectMake(15, 100, CGRectGetWidth(self.view.frame) - 30, 44) 
    self.view.addSubview(paymentTextField) 

    let bottonConstraint = NSLayoutConstraint(item: paymentTextField, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.amountLabel , attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 30) 
    bottonConstraint.identifier = "paymentTextFieldSpacing" 
    NSLayoutConstraint.activateConstraints([bottonConstraint]) 

但我得到一個錯誤:

"Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with items > and > because they have no common ancestor. Does the constraint reference items in different view hierarchies? That's illegal."

有誰知道什麼是錯?將amountLabel直接拖到故事板中的視圖中,並將「paymentTextField」以編程方式添加到相同視圖。爲什麼他們沒有共同的祖先?

回答

4

錯誤指出「因爲它們沒有共同的祖先」,這意味着它們不共享相同的父親。爲了將兩個項目之間的約束聯繫起來,他們必須有一個孩子 - 父母關係或兄弟姐妹關係。

在你的情況下,只要確保它們具有相同的父視圖,然後以編程方式添加約束。

+1

感謝您的回答。我無法弄清楚如何將amountLabel和paymentTextField作爲同一父項。我在storyboard中拖動了amountLabel,其父母應該是外部視圖。我以編程方式將paymentTextField添加到self.view,其父項也應該是外部視圖。他們怎麼會有不同的父母? – jimshicard

+1

您是否確認它們具有相同的父級,如打印paymentTextField.superview?如果他們不這樣做,只需將IBOutlet從故事板外觀拖到控制器,然後使用它將paymentTextField添加爲子視圖。 此外,請確保您在addSubview調用之後添加約束,而不是之前。 – Pauls

40

我遇到了與前面描述的相同的問題。爲了製作程序化子視圖(在您的情況下爲paymentTextField),您必須先將其添加到子視圖中,然後應用您的約束。

通過首先添加子視圖來查看,這確保兩個視圖都具有相同的父級。

很晚,但希望這可以幫助其他人。

+0

我可以驗證這一點。它發生在我嘗試激活約束但忘記將子視圖添加到超級視圖。 – christostsang

8

清單針對此問題:

  • 檢查是否激活約束之前添加的編程方式創建的視圖到其父
  • 檢查是否寫入內部viewDidLoad中()約束激活碼/ viewWillAppear中()。你應該在updateViewConstraints或viewWillLayoutSubviews中寫約束激活碼。 (suggested by vmeyer
  • 檢查您是否關閉translatingAutoresizingMaskIntoConstraints
相關問題