Skip to content

Instantly share code, notes, and snippets.

@regnerjr
Created May 12, 2017 15:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save regnerjr/d4367916b99642ca3b49252e2c59a93e to your computer and use it in GitHub Desktop.
Save regnerjr/d4367916b99642ca3b49252e2c59a93e to your computer and use it in GitHub Desktop.
import UIKit
class PossibleView: UIView {
let header: UILabel = {
let label = UILabel(frame: .zero)
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = .brown
label.numberOfLines = 0
return label
}()
dynamic let subHeading: UILabel = {
let label = UILabel(frame: .zero)
label.translatesAutoresizingMaskIntoConstraints = false
label.backgroundColor = .blue
label.numberOfLines = 0
return label
}()
let button: UIButton = {
let button = UIButton(type: .system)
button.translatesAutoresizingMaskIntoConstraints = false
button.backgroundColor = .green
return button
}()
// KVO
private var observerContext = 0
override init(frame: CGRect) {
super.init(frame: frame)
configure()
addObserver(self, forKeyPath: #keyPath(subHeading.text), options: [.new, .old], context: &observerContext)
}
deinit {
removeObserver(self, forKeyPath: #keyPath(subHeading.text), context: &observerContext)
}
@available(*, unavailable)
required init(coder: NSCoder) {
fatalError("Don't use this, use init(frame:)")
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
guard context == &observerContext else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
return
}
guard let keyPath = keyPath, keyPath == "subHeading.text" else {
return
}
guard let changeDict = change else {
return print("No changes")
}
let newValue = changeDict[.newKey] as? Optional<String>
if let nv = newValue {
layoutWithSubHeading()
} else {
layoutForNoSubHeading()
}
}
// Constraints
var subHeadingToButton: NSLayoutConstraint!
var headingToSubHeading: NSLayoutConstraint!
var headingToButton: NSLayoutConstraint!
}
fileprivate extension PossibleView {
func configure() {
backgroundColor = .purple
addSubview(header)
addSubview(subHeading)
addSubview(button)
headingToSubHeading = subHeading.topAnchor.constraint(equalTo: header.bottomAnchor, constant: 8)
subHeadingToButton = button.topAnchor.constraint(equalTo: subHeading.bottomAnchor, constant: 8)
headingToButton = header.bottomAnchor.constraint(equalTo: button.topAnchor, constant: -4)
NSLayoutConstraint.activate([
header.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8),
header.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8),
header.topAnchor.constraint(equalTo: topAnchor),
subHeading.leadingAnchor.constraint(equalTo: header.leadingAnchor),
subHeading.trailingAnchor.constraint(equalTo: header.trailingAnchor),
button.leadingAnchor.constraint(equalTo: subHeading.leadingAnchor),
button.trailingAnchor.constraint(lessThanOrEqualTo: subHeading.trailingAnchor),
])
layoutForNoSubHeading()
}
func layoutForNoSubHeading() {
headingToSubHeading.isActive = false
subHeadingToButton.isActive = false
headingToButton.isActive = true
}
func layoutWithSubHeading() {
headingToSubHeading.isActive = true
subHeadingToButton.isActive = true
headingToButton.isActive = false
}
}
import PlaygroundSupport
let view = PossibleView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
PlaygroundPage.current.liveView = view
view.header.text = "You should be layed out here"
view.subHeading.text = nil //setting this to nil, or some title will change the layout of the view
view.button.setTitle("This is a button", for: .normal)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment