Skip to content

Instantly share code, notes, and snippets.

@0111b
Created December 4, 2017 04:18
Show Gist options
  • Save 0111b/5224ab2b24c36ca9495a03c444b99eda to your computer and use it in GitHub Desktop.
Save 0111b/5224ab2b24c36ca9495a03c444b99eda to your computer and use it in GitHub Desktop.
UIView awake after
import UIKit
extension UIView {
open override func awakeAfter(using aDecoder: NSCoder) -> Any? {
let viewType = type(of: self)
let nibName = String(describing: Mirror(reflecting: self).subjectType)
let bundle = Bundle.main //Bundle(for: viewType)
//Prevents infinite loop from loadNibNamed internally-calling awakeAfterUsingCoder. Is false when called from storyboard, true when
guard !translatesAutoresizingMaskIntoConstraints
else { return self }
guard bundle.path(forResource: nibName, ofType: "nib") != nil,
let nib = bundle.loadNibNamed(nibName, owner: self, options: nil),
let replacement = nib.first as? UIView,
type(of: replacement) == viewType
else { return self }
transferProperties(to: replacement)
let constraints = reparentedConstraints(from: self, to: replacement)
for sub in subviews {
let subviewConstraints = sub.reparentedConstraints(from: self, to: replacement)
sub.removeFromSuperview()
replacement.insertSubview(sub, at: replacement.subviews.endIndex)
sub.addConstraints(subviewConstraints)
}
replacement.addConstraints(constraints)
return replacement
}
private func reparentedConstraints(from source: UIView, to target: UIView) -> [NSLayoutConstraint] {
return constraints.map { original in
let first = source == original.firstItem as? UIView ? target : original.firstItem
let second = source == original.secondItem as? UIView ? target : original.secondItem
let constraint = NSLayoutConstraint(
item: first!,
attribute: original.firstAttribute,
relatedBy: original.relation,
toItem: second,
attribute: original.secondAttribute,
multiplier: original.multiplier,
constant: original.constant)
constraint.priority = original.priority
constraint.shouldBeArchived = original.shouldBeArchived
constraint.identifier = original.identifier
constraint.isActive = original.isActive
return constraint
}
}
private func transferProperties(to target: UIView) {
target.translatesAutoresizingMaskIntoConstraints = false
target.autoresizingMask = autoresizingMask
target.isHidden = isHidden
target.tag = tag
target.isUserInteractionEnabled = isUserInteractionEnabled
target.frame = frame
target.bounds = bounds
target.clipsToBounds = clipsToBounds
// Could use better reflection of properties!
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment