Created
December 4, 2017 04:18
-
-
Save 0111b/5224ab2b24c36ca9495a03c444b99eda to your computer and use it in GitHub Desktop.
UIView awake after
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
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