Ich versuche verstehen Autolayout Einschränkungen. Im Anschluss an eine Ray W Tutorial Herausforderung (ohne eine Lösung oder eine Diskussion), sieht das Layout sollte dies wie:Constraints in Code mit swift - nicht aktivierbar
es in IB tun war einfach genug - schafft eine gelbe Ansicht mit einer Breite und Höhe, vertikal zentrierte und horizontal an den Rändern fixiert; Erstellen Sie dann Etiketten, Felder und eine Schaltfläche mit einfachen Einschränkungen in dieser Ansicht.
Meine erste Frage ist: Wenn die Etiketten eine intrinsische Inhaltsgröße haben und alles andere an die gelbe Ansicht angeheftet ist, warum muss ich dann eine feste Breite und Höhe definieren? Warum sollte er nicht vom inneren Inhalt seiner Unteransichten auf die Breite und Höhe schließen?
Umzug auf und versucht, dieses Layout in Code zu erstellen gab mir eine Fehlermeldung:
Terminating app due to uncaught exception 'NSGenericException', reason: 'Unable to activate constraint with items
<UILabel: 0x7a961d60; frame = (0 0; 0 0); text = 'Password:'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7a961e40>>
and<UIView: 0x7a96b6f0; frame = (0 0; 0 0); layer = <CALayer: 0x7a96b880>>
because they have no common ancestor. Does the constraint reference items in different view hierarchies? That's illegal.'
Zweite Frage: Was sind diese Schichten, und alle meine Ansichten sind in einem heirachy - Superview enthält die gelbe Ansicht enthält die Textbeschriftungen und Felder.
Nach vielen Schmerzen habe ich versucht, die in IB gemachten Einschränkungen exakt neu zu erstellen, aber dies fügte nur den folgenden Fehler hinzu: Konnte Bedingungen gleichzeitig nicht erfüllen.
(
"<NSLayoutConstraint:0x7ac57370 H:[UIView:0x7a96b6f0(0)]>",
"<NSLayoutConstraint:0x7ac57400 H:|-(8)-[UILabel:0x7a96bb50'Username:'] (Names: '|':UIView:0x7a96b6f0)>",
"<NSLayoutConstraint:0x7ac57430 UILabel:0x7a96bb50'Username:'.trailing == UITextField:0x7a961020.leading + 8>",
"<NSLayoutConstraint:0x7ac57520 UITextField:0x7a961020.trailing == UIView:0x7a96b6f0.trailing - 8>")
Letzte Frage (n): Woher weiß ich, welche Ansicht 0x7aetc ist? Und wo ist diese Einschränkung in meinem Code? Der Rest sieht gut aus (?).
Ich muss etwas sehr falsch auf einer grundlegenden Ebene tun.
Hier ist mein Code:
import UIKit
class ViewController: UIViewController {
let centerView = UIView()
let usernameLabel = UILabel()
let passwordLabel = UILabel()
let usernameField = UITextField()
let passwordField = UITextField()
let submitButton = UIButton()
override func viewDidLoad() {
super.viewDidLoad()
centerView.backgroundColor = UIColor.yellowColor()
usernameLabel.text = "Username:"
passwordLabel.text = "Password:"
usernameField.borderStyle = .RoundedRect
passwordField.borderStyle = .RoundedRect
submitButton.setTitle("Submit!", forState: .Normal)
submitButton.setTitleColor(UIColor.blackColor(), forState: .Normal)
submitButton.setTitleColor(UIColor.blueColor(), forState: .Highlighted)
view.addSubview(centerView)
self.centerView.addSubview(usernameField)
self.centerView.addSubview(passwordField)
self.centerView.addSubview(usernameLabel)
self.centerView.addSubview(submitButton)
let constraintCenterViewHeight = NSLayoutConstraint(item: centerView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 0)
let constraintCenterViewWidth = NSLayoutConstraint(item: centerView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 0)
let constraintCenterViewCenterX = NSLayoutConstraint(item: centerView, attribute: .CenterX, relatedBy: .Equal, toItem: view, attribute: .CenterX, multiplier: 1.0, constant: 0)
let constraintCenterViewCenterY = NSLayoutConstraint(item: centerView, attribute: .CenterY, relatedBy: .Equal, toItem: view, attribute: .CenterY, multiplier: 1.0, constant: 0)
let constraintUsernameLabelHLeading = NSLayoutConstraint(item: usernameLabel, attribute: .Leading, relatedBy: .Equal, toItem: centerView, attribute: .Leading, multiplier: 1.0, constant: 8)
let constraintUsernameLabelHTrailing = NSLayoutConstraint(item: usernameLabel, attribute: .Trailing, relatedBy: .Equal, toItem: usernameField, attribute: .Leading, multiplier: 1.0, constant: 8)
let constraintUsernameLabelAlignBottom = NSLayoutConstraint(item: usernameLabel, attribute: .Bottom, relatedBy: .Equal, toItem: usernameField, attribute: .Bottom, multiplier: 1.0, constant: 0)
let constraintUsernameFieldVTop = NSLayoutConstraint(item: usernameField, attribute: .Top, relatedBy: .Equal, toItem: centerView, attribute: .Top, multiplier: 1.0, constant: 8)
let constraintUsernameFieldHTrailing = NSLayoutConstraint(item: usernameField, attribute: .Trailing, relatedBy: .Equal, toItem: centerView, attribute: .Trailing, multiplier: 1.0, constant: -8)
let constraintUsernameFieldVBottom = NSLayoutConstraint(item: usernameField, attribute: .Bottom, relatedBy: .Equal, toItem: passwordField, attribute: .Top, multiplier: 1.0, constant: 8)
let constraintPasswordLabelHLeading = NSLayoutConstraint(item: passwordLabel, attribute: .Leading, relatedBy: .Equal, toItem: centerView, attribute: .Leading, multiplier: 1.0, constant: 8)
let constraintPasswordLabelHTrailing = NSLayoutConstraint(item: passwordLabel, attribute: .Trailing, relatedBy: .Equal, toItem: passwordField, attribute: .Leading, multiplier: 1.0, constant: 8)
let constraintPasswordLabelAlignBottom = NSLayoutConstraint(item: passwordLabel, attribute: .Bottom, relatedBy: .Equal, toItem: passwordField, attribute: .Bottom, multiplier: 1.0, constant: 0)
let constraintPasswordFieldHTrailing = NSLayoutConstraint(item: passwordField, attribute: .Trailing, relatedBy: .Equal, toItem: centerView, attribute: .Trailing, multiplier: 1.0, constant: -8)
centerView.setTranslatesAutoresizingMaskIntoConstraints(false)
usernameLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
usernameField.setTranslatesAutoresizingMaskIntoConstraints(false)
passwordField.setTranslatesAutoresizingMaskIntoConstraints(false)
passwordLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
// submitButton.setTranslatesAutoresizingMaskIntoConstraints(false)
NSLayoutConstraint.activateConstraints([constraintCenterViewHeight, constraintCenterViewWidth, constraintCenterViewCenterX, constraintCenterViewCenterY, constraintUsernameLabelHLeading,
constraintUsernameLabelHTrailing, constraintUsernameLabelAlignBottom, constraintUsernameFieldVTop, constraintUsernameFieldHTrailing, constraintUsernameFieldVBottom, constraintPasswordLabelHLeading, constraintPasswordLabelHTrailing, constraintPasswordLabelAlignBottom, constraintPasswordFieldHTrailing])
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Ich suchte Tage in diesem Code und sah nie die fehlende subview, noch die Breite und Höhe als 0! Ah-ha, (als ich schrieb, dass ich es nicht verstanden habe) dachte mein stumpfes altes Gehirn, dass die Hinterkante von usernameLabel zur Vorderkante von usernameField 8 Punkte weiter entlang der Y- oder horizontalen Achse sein sollte. ABER das ist nur ein weiterer dummer Fehler. Ich möchte die Trailing-Kante von usernameLabel an die Vorderkante von usernameField entlang der Y- oder horizontalen Achse zurückführen. Sehr leid und sehr dankbar, dass Sie darauf hingewiesen haben. Es ist toll zu wissen, dass dieses Zeug funktioniert, wenn Sie es verstehen. – DrWhat