import UIKit
protocol ViewComponent : AnyObject {
///
func isAncestor(of descendant: Self) -> Bool
///
func isDescendant(of ancestor: Self) -> Bool
///
func detach()
}
extension ViewComponent where Self : UIView {
///
func attach<Ancestor>(
to ancestor: Ancestor,
performing attachment: (
(ancestor: Ancestor, current: Self)
) -> Void
) where Ancestor : UIView {
attachment((ancestor, self))
assert(
ancestor.isAncestor(of: self),
"""
After attachment closure was called, `ancestor` \
must be an ancestor of `self`.
"""
)
}
///
/* default */ func detach() {
removeFromSuperview()
}
}
extension ViewComponent where Self : UIViewController {
///
func attach<Ancestor>(
to ancestor: Ancestor,
performing attachment: (
(ancestor: Ancestor, current: Self)
) -> Void
) where Ancestor : UIViewController {
ancestor.addChildViewController(self)
attachment((ancestor, self))
assert(
ancestor.isAncestor(of: self) &&
ancestor.view.isAncestor(of: self.view),
"""
After attachment closure was called, `ancestor` \
must be an ancestor of `self` and also `ancestor.view` \
must be an ancestor of `self.view`.
"""
)
didMove(toParentViewController: ancestor)
}
///
/* default */ func detach() {
willMove(toParentViewController: nil)
view.detach()
removeFromParentViewController()
}
}
extension UIView : ViewComponent {
///
func isAncestor(of descendant: UIView) -> Bool {
var ancestor = descendant.superview
while let someAncestor = ancestor {
if self === someAncestor {
return true
}
ancestor = someAncestor.superview
}
return false
}
///
func isDescendant(of ancestor: UIView) -> Bool {
return ancestor.isAncestor(of: self)
}
}
extension UIViewController : ViewComponent {
///
func isAncestor(of descendant: UIViewController) -> Bool {
var ancestor = descendant.parent
while let someAncestor = ancestor {
if self === someAncestor {
return true
}
ancestor = someAncestor.parent
}
return false
}
///
func isDescendant(of ancestor: UIViewController) -> Bool {
return ancestor.isAncestor(of: self)
}
}
Last active
December 24, 2017 12:16
-
-
Save DevAndArtist/7dbe7f505265dc292aa6076a54ced459 to your computer and use it in GitHub Desktop.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment