Skip to content

Instantly share code, notes, and snippets.

@jakehawken
Last active February 3, 2020 00:38
Show Gist options
  • Save jakehawken/966a6d57e18d1d323cdad58e1f58f838 to your computer and use it in GitHub Desktop.
Save jakehawken/966a6d57e18d1d323cdad58e1f58f838 to your computer and use it in GitHub Desktop.
I'm tired of Chisel crapping the bed. Time to roll a native solution.
extension UIApplication {
static func printAppVCHierarchy() {
shared.printViewControllerHierarchy()
}
func printViewControllerHierarchy() {
guard let rootVC = keyWindow?.rootViewController else {
print("Print failed. No root view controller found.")
return
}
rootVC.printViewControllerHierarchy()
}
}
private extension UIViewController {
func printViewControllerHierarchy() {
let strings = vcHierarchyStrings().joined(separator: "\n")
print("\nAPPLICATION VIEW CONTROLLER HIERARCHY>>>>>>>>>>>>>>>>>>>>")
print(strings)
print("<<<<<<<<<<<<<<<<<<<<APPLICATION VIEW CONTROLLER HIERARCHY\n")
}
func vcHierarchyStrings(level: Int = 0) -> [String] {
let level = max(0, level)
let leadingSpace = repeatElement(" ", count: level * 2).joined()
var output = [String]()
output.append("\(leadingSpace)\(self)")
let subVCs: [UIViewController]
if let navCon = self as? UINavigationController {
subVCs = navCon.viewControllers
}
else if let tabBar = self as? UITabBarController {
subVCs = tabBar.viewControllers ?? []
}
else if let pageVC = self as? UIPageViewController {
subVCs = pageVC.viewControllers ?? []
}
else {
subVCs = []
}
subVCs.forEach {
output += $0.vcHierarchyStrings(level: level + 1)
}
return output
}
}
extension UIView {
internal func printHierarchy() {
let hierarchyStrings = viewHierarchyStrings()
print("\nVIEW HIERARCHY: >>>>>>>>>>>>>>>>>>>>")
print(hierarchyStrings.joined(separator: "\n"))
print("<<<<<<<<<<<<<<<<<<<< VIEW HIERARCHY\n")
}
private func viewHierarchyStrings(level: Int = 0) -> [String] {
let level = max(0, level)
let leadingSpace = repeatElement(" ", count: level * 2).joined()
var output = [String]()
output.append("\(leadingSpace){\(viewHeader())")
subviews.forEach {
output += $0.viewHierarchyStrings(level: level + 1)
}
output.append("\(leadingSpace)}")
return output
}
private func viewHeader() -> String {
let typeName = String(describing: type(of: self))
let memAdrss = memoryAddressStringFor(self)
return "\(typeName)(\(memAdrss))"
}
}
private func memoryAddressStringFor(_ obj: AnyObject) -> String {
return "\(Unmanaged.passUnretained(obj).toOpaque())"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment