-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update LearnAboutAutoLayout.playground
- Loading branch information
Eric Hyche
committed
Aug 9, 2017
1 parent
68c75d0
commit d7f8d10
Showing
21 changed files
with
511 additions
and
0 deletions.
There are no files selected for viewing
44 changes: 44 additions & 0 deletions
44
...AutoLayout.playground/Pages/Constraint Debug Descriptions.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import UIKit | ||
import PlaygroundSupport | ||
|
||
// This is our sample container view which allows us | ||
// to adjust the width and height of the container | ||
let liveView = EHAdjustableContainerView(frame: CGRect(x: 0.0, y: 0.0, width: 512.0, height: 512.0)) | ||
let container = liveView.containerView | ||
|
||
func createButton(withTitle title: String) -> UIButton { | ||
let button = UIButton(frame: .zero) | ||
button.setTitle(title, for: .normal) | ||
button.setTitleColor(UIColor.white, for: .normal) | ||
button.backgroundColor = UIColor.darkGray | ||
return button | ||
} | ||
|
||
let shortButton = createButton(withTitle: "Short") | ||
let longButton = createButton(withTitle: "Much Longer Button Title") | ||
|
||
shortButton.translatesAutoresizingMaskIntoConstraints = false | ||
container.addSubview(shortButton) | ||
|
||
longButton.translatesAutoresizingMaskIntoConstraints = false | ||
container.addSubview(longButton) | ||
|
||
// |-[short]-(8)-[long]-| | ||
shortButton.leadingAnchor.constraint(equalTo: container.layoutMarginsGuide.leadingAnchor).isActive = true | ||
let betwixt = longButton.leadingAnchor.constraint(equalTo: shortButton.trailingAnchor, constant: 8.0) | ||
betwixt.identifier = "Space Between Short and Long" | ||
betwixt.isActive = true | ||
longButton.trailingAnchor.constraint(equalTo: container.layoutMarginsGuide.trailingAnchor).isActive = true | ||
|
||
container.layoutMarginsGuide.bottomAnchor.constraint(equalTo: shortButton.bottomAnchor, constant: 20.0).isActive = true | ||
container.layoutMarginsGuide.bottomAnchor.constraint(equalTo: longButton.bottomAnchor, constant: 20.0).isActive = true | ||
|
||
shortButton.widthAnchor.constraint(equalTo: longButton.widthAnchor).isActive = true | ||
|
||
for constraint in container.constraints { | ||
print("\(constraint)") | ||
} | ||
|
||
|
||
PlaygroundPage.current.needsIndefiniteExecution = true | ||
PlaygroundPage.current.liveView = liveView |
6 changes: 6 additions & 0 deletions
6
...ayout.playground/Pages/Constraint Debug Descriptions.xcplaygroundpage/timeline.xctimeline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Timeline | ||
version = "3.0"> | ||
<TimelineItems> | ||
</TimelineItems> | ||
</Timeline> |
101 changes: 101 additions & 0 deletions
101
LearnAboutAutoLayout.playground/Pages/Dynamic Height Columns.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import UIKit | ||
import PlaygroundSupport | ||
|
||
// This is our sample container view which allows us | ||
// to adjust the width and height of the container | ||
let liveView = EHAdjustableContainerView(frame: CGRect(x: 0.0, y: 0.0, width: 512.0, height: 512.0)) | ||
let container = liveView.containerView | ||
|
||
let labelFontSizeSmall: CGFloat = 16.0 | ||
let labelFontSizeLarge: CGFloat = 32.0 | ||
|
||
func label(withText text: String) -> UILabel { | ||
let label = UILabel(frame: .zero) | ||
label.translatesAutoresizingMaskIntoConstraints = false | ||
label.textColor = UIColor.black | ||
label.font = UIFont.boldSystemFont(ofSize: labelFontSizeSmall) | ||
// label.font = UIFont.boldSystemFont(ofSize: labelFontSizeLarge) | ||
label.text = text | ||
return label | ||
} | ||
|
||
func textField(withPlaceholder placeholder: String) -> UITextField { | ||
let textField = UITextField(frame: .zero) | ||
textField.translatesAutoresizingMaskIntoConstraints = false | ||
textField.borderStyle = .roundedRect | ||
textField.placeholder = placeholder | ||
|
||
return textField | ||
} | ||
|
||
let firstLabel = label(withText: "First Name") | ||
let firstTextField = textField(withPlaceholder: "Enter first name") | ||
let middleLabel = label(withText: "Middle Name") | ||
let middleTextField = textField(withPlaceholder: "Enter middle name") | ||
let lastLabel = label(withText: "Last Name") | ||
let lastTextField = textField(withPlaceholder: "Enter last name") | ||
|
||
container.addSubview(firstLabel) | ||
container.addSubview(firstTextField) | ||
container.addSubview(middleLabel) | ||
container.addSubview(middleTextField) | ||
container.addSubview(lastLabel) | ||
container.addSubview(lastTextField) | ||
|
||
// |-[firstLabel]-(8)-[firstTextField]-| | ||
firstLabel.leadingAnchor.constraint(equalTo: container.layoutMarginsGuide.leadingAnchor).isActive = true | ||
firstTextField.leadingAnchor.constraint(equalTo: firstLabel.trailingAnchor, constant: 8.0).isActive = true | ||
firstTextField.trailingAnchor.constraint(equalTo: container.layoutMarginsGuide.trailingAnchor).isActive = true | ||
|
||
// Middle label and text field | ||
middleLabel.leadingAnchor.constraint(equalTo: firstLabel.leadingAnchor).isActive = true | ||
middleTextField.leadingAnchor.constraint(equalTo: middleLabel.trailingAnchor, constant: 8.0).isActive = true | ||
middleTextField.trailingAnchor.constraint(equalTo: firstTextField.trailingAnchor).isActive = true | ||
|
||
|
||
lastLabel.leadingAnchor.constraint(equalTo: firstLabel.leadingAnchor).isActive = true | ||
lastTextField.leadingAnchor.constraint(equalTo: lastLabel.trailingAnchor, constant: 8.0).isActive = true | ||
lastTextField.trailingAnchor.constraint(equalTo: firstTextField.trailingAnchor).isActive = true | ||
|
||
// Align baselines | ||
firstLabel.firstBaselineAnchor.constraint(equalTo: firstTextField.firstBaselineAnchor).isActive = true | ||
middleLabel.firstBaselineAnchor.constraint(equalTo: middleTextField.firstBaselineAnchor).isActive = true | ||
lastLabel.firstBaselineAnchor.constraint(equalTo: lastTextField.firstBaselineAnchor).isActive = true | ||
|
||
// Make all text field widths the same | ||
firstTextField.widthAnchor.constraint(equalTo: middleTextField.widthAnchor).isActive = true | ||
firstTextField.widthAnchor.constraint(equalTo: lastTextField.widthAnchor).isActive = true | ||
|
||
// Handle where either the label or text field could be taller | ||
func setupRequiredMinWithOptionalEquality(anchorY1: NSLayoutYAxisAnchor, anchorY2: NSLayoutYAxisAnchor, constant: CGFloat, priority: UILayoutPriority) { | ||
anchorY1.constraint(greaterThanOrEqualTo: anchorY2, constant: constant).isActive = true | ||
let equality = anchorY1.constraint(equalTo: anchorY2, constant: constant) | ||
equality.priority = priority | ||
equality.isActive = true | ||
} | ||
|
||
setupRequiredMinWithOptionalEquality(anchorY1: firstLabel.topAnchor, anchorY2: container.layoutMarginsGuide.topAnchor, constant: 20.0, priority: 249) | ||
setupRequiredMinWithOptionalEquality(anchorY1: firstTextField.topAnchor, anchorY2: container.layoutMarginsGuide.topAnchor, constant: 20.0, priority: 249) | ||
|
||
setupRequiredMinWithOptionalEquality(anchorY1: middleLabel.topAnchor, anchorY2: firstLabel.bottomAnchor, constant: 8.0, priority: 249) | ||
setupRequiredMinWithOptionalEquality(anchorY1: middleTextField.topAnchor, anchorY2: firstTextField.bottomAnchor, constant: 8.0, priority: 249) | ||
|
||
setupRequiredMinWithOptionalEquality(anchorY1: lastLabel.topAnchor, anchorY2: middleLabel.bottomAnchor, constant: 8.0, priority: 249) | ||
setupRequiredMinWithOptionalEquality(anchorY1: lastTextField.topAnchor, anchorY2: middleTextField.bottomAnchor, constant: 8.0, priority: 249) | ||
|
||
|
||
// We set the content hugging priority so that | ||
// the labels have a higher content hugging priority | ||
// than do the text fields. What happens if we reverse these? | ||
let labelPriority = UILayoutPriorityDefaultLow + 1 | ||
let textFieldPriority = UILayoutPriorityDefaultLow | ||
firstLabel.setContentHuggingPriority(labelPriority, for: .horizontal) | ||
middleLabel.setContentHuggingPriority(labelPriority, for: .horizontal) | ||
lastLabel.setContentHuggingPriority(labelPriority, for: .horizontal) | ||
firstTextField.setContentHuggingPriority(textFieldPriority, for: .horizontal) | ||
middleTextField.setContentHuggingPriority(textFieldPriority, for: .horizontal) | ||
lastTextField.setContentHuggingPriority(textFieldPriority, for: .horizontal) | ||
|
||
|
||
PlaygroundPage.current.needsIndefiniteExecution = true | ||
PlaygroundPage.current.liveView = liveView |
6 changes: 6 additions & 0 deletions
6
...utAutoLayout.playground/Pages/Dynamic Height Columns.xcplaygroundpage/timeline.xctimeline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Timeline | ||
version = "3.0"> | ||
<TimelineItems> | ||
</TimelineItems> | ||
</Timeline> |
33 changes: 33 additions & 0 deletions
33
LearnAboutAutoLayout.playground/Pages/Equal Width Views.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import UIKit | ||
import PlaygroundSupport | ||
|
||
// This is our sample container view which allows us | ||
// to adjust the width and height of the container | ||
let liveView = EHAdjustableContainerView(frame: CGRect(x: 0.0, y: 0.0, width: 512.0, height: 512.0)) | ||
|
||
let yellow = UIView(frame: .zero) | ||
yellow.translatesAutoresizingMaskIntoConstraints = false | ||
yellow.backgroundColor = UIColor.yellow | ||
|
||
liveView.containerView.addSubview(yellow) | ||
|
||
let green = UIView(frame: .zero) | ||
green.translatesAutoresizingMaskIntoConstraints = false | ||
green.backgroundColor = UIColor.green | ||
|
||
liveView.containerView.addSubview(green) | ||
|
||
yellow.leadingAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.leadingAnchor).isActive = true | ||
green.leadingAnchor.constraint(equalTo: yellow.trailingAnchor, constant: 8.0).isActive = true | ||
green.trailingAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.trailingAnchor).isActive = true | ||
// Attach the top of the yellow and green | ||
yellow.topAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.topAnchor).isActive = true | ||
green.topAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.topAnchor).isActive = true | ||
// Attach the bottom of yellow and green | ||
yellow.bottomAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.bottomAnchor).isActive = true | ||
green.bottomAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.bottomAnchor).isActive = true | ||
// Now set the width of yellow and green to be the same | ||
yellow.widthAnchor.constraint(equalTo: green.widthAnchor).isActive = true | ||
|
||
PlaygroundPage.current.needsIndefiniteExecution = true | ||
PlaygroundPage.current.liveView = liveView |
6 changes: 6 additions & 0 deletions
6
LearnAboutAutoLayout.playground/Pages/Equal Width Views.xcplaygroundpage/timeline.xctimeline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Timeline | ||
version = "3.0"> | ||
<TimelineItems> | ||
</TimelineItems> | ||
</Timeline> |
93 changes: 93 additions & 0 deletions
93
LearnAboutAutoLayout.playground/Pages/Fixed Height Columns.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import UIKit | ||
import PlaygroundSupport | ||
|
||
// This is our sample container view which allows us | ||
// to adjust the width and height of the container | ||
let liveView = EHAdjustableContainerView(frame: CGRect(x: 0.0, y: 0.0, width: 512.0, height: 512.0)) | ||
let container = liveView.containerView | ||
|
||
let labelFontSizeSmall: CGFloat = 16.0 | ||
let labelFontSizeLarge: CGFloat = 32.0 | ||
|
||
func label(withText text: String) -> UILabel { | ||
let label = UILabel(frame: .zero) | ||
label.translatesAutoresizingMaskIntoConstraints = false | ||
label.textColor = UIColor.black | ||
label.font = UIFont.boldSystemFont(ofSize: labelFontSizeSmall) | ||
// label.font = UIFont.boldSystemFont(ofSize: labelFontSizeLarge) | ||
label.text = text | ||
return label | ||
} | ||
|
||
func textField(withPlaceholder placeholder: String) -> UITextField { | ||
let textField = UITextField(frame: .zero) | ||
textField.translatesAutoresizingMaskIntoConstraints = false | ||
textField.borderStyle = .roundedRect | ||
textField.placeholder = placeholder | ||
|
||
return textField | ||
} | ||
|
||
let firstLabel = label(withText: "First Name") | ||
let firstTextField = textField(withPlaceholder: "Enter first name") | ||
let middleLabel = label(withText: "Middle Name") | ||
let middleTextField = textField(withPlaceholder: "Enter middle name") | ||
let lastLabel = label(withText: "Last Name") | ||
let lastTextField = textField(withPlaceholder: "Enter last name") | ||
|
||
container.addSubview(firstLabel) | ||
container.addSubview(firstTextField) | ||
container.addSubview(middleLabel) | ||
container.addSubview(middleTextField) | ||
container.addSubview(lastLabel) | ||
container.addSubview(lastTextField) | ||
|
||
// |-[firstLabel]-(8)-[firstTextField]-| | ||
firstLabel.leadingAnchor.constraint(equalTo: container.layoutMarginsGuide.leadingAnchor).isActive = true | ||
firstTextField.leadingAnchor.constraint(equalTo: firstLabel.trailingAnchor, constant: 8.0).isActive = true | ||
firstTextField.trailingAnchor.constraint(equalTo: container.layoutMarginsGuide.trailingAnchor).isActive = true | ||
|
||
// Middle label and text field | ||
middleLabel.leadingAnchor.constraint(equalTo: firstLabel.leadingAnchor).isActive = true | ||
middleTextField.leadingAnchor.constraint(equalTo: middleLabel.trailingAnchor, constant: 8.0).isActive = true | ||
middleTextField.trailingAnchor.constraint(equalTo: firstTextField.trailingAnchor).isActive = true | ||
|
||
|
||
lastLabel.leadingAnchor.constraint(equalTo: firstLabel.leadingAnchor).isActive = true | ||
lastTextField.leadingAnchor.constraint(equalTo: lastLabel.trailingAnchor, constant: 8.0).isActive = true | ||
lastTextField.trailingAnchor.constraint(equalTo: firstTextField.trailingAnchor).isActive = true | ||
|
||
// Align baselines | ||
firstLabel.firstBaselineAnchor.constraint(equalTo: firstTextField.firstBaselineAnchor).isActive = true | ||
middleLabel.firstBaselineAnchor.constraint(equalTo: middleTextField.firstBaselineAnchor).isActive = true | ||
lastLabel.firstBaselineAnchor.constraint(equalTo: lastTextField.firstBaselineAnchor).isActive = true | ||
|
||
// Make all text field widths the same | ||
firstTextField.widthAnchor.constraint(equalTo: middleTextField.widthAnchor).isActive = true | ||
firstTextField.widthAnchor.constraint(equalTo: lastTextField.widthAnchor).isActive = true | ||
|
||
// Pin first label to top margin | ||
firstLabel.topAnchor.constraint(equalTo: container.layoutMarginsGuide.topAnchor).isActive = true | ||
|
||
|
||
// These constraints put space between the rows. But we | ||
// are assuming that the text fields are taller than the | ||
// labels. What happens if they are not? | ||
middleTextField.topAnchor.constraint(equalTo: firstTextField.bottomAnchor, constant: 20.0).isActive = true | ||
lastTextField.topAnchor.constraint(equalTo: middleTextField.bottomAnchor, constant: 20.0).isActive = true | ||
|
||
// We set the content hugging priority so that | ||
// the labels have a higher content hugging priority | ||
// than do the text fields. What happens if we reverse these? | ||
let labelPriority = UILayoutPriorityDefaultLow + 1 | ||
let textFieldPriority = UILayoutPriorityDefaultLow | ||
firstLabel.setContentHuggingPriority(labelPriority, for: .horizontal) | ||
middleLabel.setContentHuggingPriority(labelPriority, for: .horizontal) | ||
lastLabel.setContentHuggingPriority(labelPriority, for: .horizontal) | ||
firstTextField.setContentHuggingPriority(textFieldPriority, for: .horizontal) | ||
middleTextField.setContentHuggingPriority(textFieldPriority, for: .horizontal) | ||
lastTextField.setContentHuggingPriority(textFieldPriority, for: .horizontal) | ||
|
||
|
||
PlaygroundPage.current.needsIndefiniteExecution = true | ||
PlaygroundPage.current.liveView = liveView |
6 changes: 6 additions & 0 deletions
6
...boutAutoLayout.playground/Pages/Fixed Height Columns.xcplaygroundpage/timeline.xctimeline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Timeline | ||
version = "3.0"> | ||
<TimelineItems> | ||
</TimelineItems> | ||
</Timeline> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
...AboutAutoLayout.playground/Pages/Proportional Width Views.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import UIKit | ||
import PlaygroundSupport | ||
|
||
// This is our sample container view which allows us | ||
// to adjust the width and height of the container | ||
let liveView = EHAdjustableContainerView(frame: CGRect(x: 0.0, y: 0.0, width: 512.0, height: 512.0)) | ||
|
||
let purple = UIView(frame: .zero) | ||
purple.translatesAutoresizingMaskIntoConstraints = false | ||
purple.backgroundColor = UIColor.purple | ||
|
||
liveView.containerView.addSubview(purple) | ||
|
||
let orange = UIView(frame: .zero) | ||
orange.translatesAutoresizingMaskIntoConstraints = false | ||
orange.backgroundColor = UIColor.orange | ||
|
||
liveView.containerView.addSubview(orange) | ||
|
||
purple.leadingAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.leadingAnchor).isActive = true | ||
orange.leadingAnchor.constraint(equalTo: purple.trailingAnchor, constant: 8.0).isActive = true | ||
orange.trailingAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.trailingAnchor).isActive = true | ||
// Attach the top of the yellow and green | ||
purple.topAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.topAnchor).isActive = true | ||
orange.topAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.topAnchor).isActive = true | ||
// Attach the bottom of yellow and green | ||
purple.bottomAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.bottomAnchor).isActive = true | ||
orange.bottomAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.bottomAnchor).isActive = true | ||
// Now set orange's width to be 2x of purple's width | ||
orange.widthAnchor.constraint(equalTo: purple.widthAnchor, multiplier: 2.0).isActive = true | ||
|
||
PlaygroundPage.current.needsIndefiniteExecution = true | ||
PlaygroundPage.current.liveView = liveView |
6 changes: 6 additions & 0 deletions
6
...AutoLayout.playground/Pages/Proportional Width Views.xcplaygroundpage/timeline.xctimeline
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<Timeline | ||
version = "3.0"> | ||
<TimelineItems> | ||
</TimelineItems> | ||
</Timeline> |
37 changes: 37 additions & 0 deletions
37
...oLayout.playground/Pages/Proportional Width with Optional.xcplaygroundpage/Contents.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import UIKit | ||
import PlaygroundSupport | ||
|
||
// This is our sample container view which allows us | ||
// to adjust the width and height of the container | ||
let liveView = EHAdjustableContainerView(frame: CGRect(x: 0.0, y: 0.0, width: 512.0, height: 512.0)) | ||
|
||
let blue = UIView(frame: .zero) | ||
blue.translatesAutoresizingMaskIntoConstraints = false | ||
blue.backgroundColor = UIColor.blue | ||
|
||
liveView.containerView.addSubview(blue) | ||
|
||
let red = UIView(frame: .zero) | ||
red.translatesAutoresizingMaskIntoConstraints = false | ||
red.backgroundColor = UIColor.red | ||
|
||
liveView.containerView.addSubview(red) | ||
|
||
blue.leadingAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.leadingAnchor).isActive = true | ||
red.leadingAnchor.constraint(equalTo: blue.trailingAnchor, constant: 8.0).isActive = true | ||
red.trailingAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.trailingAnchor).isActive = true | ||
// Attach the top of the yellow and green | ||
blue.topAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.topAnchor).isActive = true | ||
red.topAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.topAnchor).isActive = true | ||
// Attach the bottom of yellow and green | ||
blue.bottomAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.bottomAnchor).isActive = true | ||
red.bottomAnchor.constraint(equalTo: liveView.containerView.layoutMarginsGuide.bottomAnchor).isActive = true | ||
// Now set red's width to be 2x of blue's width (@750) | ||
let widthConstraint = red.widthAnchor.constraint(equalTo: blue.widthAnchor, multiplier: 2.0) | ||
widthConstraint.priority = UILayoutPriorityDefaultHigh | ||
widthConstraint.isActive = true | ||
|
||
blue.widthAnchor.constraint(greaterThanOrEqualToConstant: 50.0).isActive = true | ||
|
||
PlaygroundPage.current.needsIndefiniteExecution = true | ||
PlaygroundPage.current.liveView = liveView |
Oops, something went wrong.