Skip to content

Commit

Permalink
feat: CustomHostingController
Browse files Browse the repository at this point in the history
- Add CustomHostingController
- Use @_spi attributes for CustomView/Window loading
  • Loading branch information
maximkrouk committed Dec 22, 2023
1 parent 177a60c commit 8750c34
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,13 @@ open class CustomCocoaViewController:
@Handler<Void>
public var onViewDidLayout

#if !canImport(CocoaExtensionsMacros)
open override func loadView() {
guard !tryLoadCustomContentView() else { return }
super.loadView()
}
#endif


open override func viewDidLoad() {
super.viewDidLoad()
Expand Down Expand Up @@ -88,11 +91,13 @@ open class CustomCocoaViewController:
_onDismiss()
}

/// Use `override _init` instead of overriding this initializer
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self._init()
}

/// Use `override _init` instead of overriding this initializer
public required init?(coder: NSCoder) {
super.init(coder: coder)
self._init()
Expand All @@ -106,7 +111,6 @@ open class CustomCocoaViewController:
CocoaViewController,
CustomCocoaViewControllerProtocol
{

private(set) open var isVisible = false

@Handler<Void>
Expand All @@ -133,10 +137,12 @@ open class CustomCocoaViewController:
@Handler<Void>
public var onViewDidLayout

#if !canImport(CocoaExtensionsMacros)
open override func loadView() {
guard !tryLoadCustomContentView() else { return }
super.loadView()
}
#endif

open override func viewDidLoad() {
super.viewDidLoad()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,26 @@ open class CustomCocoaWindowController:
@Handler<Void>
public var onWindowDidLoad

/// Use `override _init` instead of overriding this initializer
public override init(window: CocoaWindow?) {
super.init(window: window)
self._init()
}

/// Use `override _init` instead of overriding this initializer
public required init?(coder: NSCoder) {
super.init(coder: coder)
self._init()
}

open func _init() {}

#if !canImport(CocoaExtensionsMacros)
open override func loadWindow() {
guard !tryLoadCustomWindow() else { return }
super.loadWindow()
}
#endif

open func _init() {}

open override func windowWillLoad() {
super.windowWillLoad()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
#if canImport(SwiftUI)
import DeclarativeConfiguration
import CocoaAliases
import SwiftUI

extension CocoaHostingController where Content: ExpressibleByNilLiteral {
public convenience init() {
self.init(rootView: nil)
}
}

#if canImport(UIKit) && !os(watchOS)

extension CustomHostingController: NavigationControllerDynamicOverridable {}

open class CustomHostingController<Content: View>:
CocoaHostingController<Content>,
CustomCocoaViewControllerProtocol
{
private(set) open var isVisible = false

@OptionalDataSource<Void, UINavigationController?>
public var overrideNavigationController

override open var navigationController: UINavigationController? {
_overrideNavigationController() ?? super.navigationController
}

@Handler<Void>
public var onDismiss

@Handler<Void>
public var onViewDidLoad

@Handler<Void>
public var onViewWillAppear

@Handler<Void>
public var onViewDidAppear

@Handler<Void>
public var onViewWillDisappear

@Handler<Void>
public var onViewDidDisappear

@Handler<Void>
public var onViewWillLayout

@Handler<Void>
public var onViewDidLayout

open override func viewDidLoad() {
super.viewDidLoad()
_onViewDidLoad()
}

open override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
_onViewWillAppear()
}

open override func viewDidAppear(_ animated: Bool) {
isVisible = true
super.viewDidAppear(animated)
_onViewDidAppear()
}

open override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
_onViewWillDisappear()
}

open override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
_onViewDidDisappear()
isVisible = false
}

open override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
_onViewWillLayout()
}

open override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
_onViewDidLayout()
}

open override func dismiss(animated: Bool, completion: (() -> Void)? = nil) {
super.dismiss(animated: animated, completion: completion)
_onDismiss()
}

/// Use `override _init` instead of overriding this initializer
public override init(rootView: Content) {
super.init(rootView: rootView)
self._init()
}

/// Use `override _init` instead of overriding this initializer
public override init?(coder: NSCoder, rootView: Content) {
super.init(coder: coder, rootView: rootView)
self._init()
}

/// Use `override _init` instead of overriding this initializer
public required init?(coder: NSCoder) {
super.init(coder: coder)
self._init()
}

/// Only for `override` purposes, do not call directly
open func _init() {}
}

#elseif canImport(AppKit)
import DeclarativeConfiguration
import CocoaAliases
import SwiftUI

open class CustomHostingController<Content: View>:
CocoaHostingController<Content>,
CustomCocoaViewControllerProtocol
{
private(set) open var isVisible = false

@Handler<Void>
public var onDismiss

@Handler<Void>
public var onViewDidLoad

@Handler<Void>
public var onViewWillAppear

@Handler<Void>
public var onViewDidAppear

@Handler<Void>
public var onViewWillDisappear

@Handler<Void>
public var onViewDidDisappear

@Handler<Void>
public var onViewWillLayout

@Handler<Void>
public var onViewDidLayout

open override func viewDidLoad() {
super.viewDidLoad()
_onViewDidLoad()
}

open override func viewWillAppear() {
super.viewWillAppear()
_onViewWillAppear()
}

open override func viewDidAppear() {
isVisible = true
super.viewDidAppear()
_onViewDidAppear()
}

open override func viewWillDisappear() {
super.viewWillDisappear()
_onViewWillDisappear()
}

open override func viewDidDisappear() {
super.viewDidDisappear()
_onViewDidDisappear()
isVisible = false
}

open override func viewWillLayout() {
super.viewWillLayout()
_onViewWillLayout()
}

open override func viewDidLayout() {
super.viewDidLayout()
_onViewDidLayout()
}

open override func dismiss(_ sender: Any?) {
super.dismiss(sender)
self._onDismiss()
}

/// Use `override _init` instead of overriding this initializer
public override init(rootView: Content) {
super.init(rootView: rootView)
self._init()
}

/// Use `override _init` instead of overriding this initializer
public override init?(coder: NSCoder, rootView: Content) {
super.init(coder: coder, rootView: rootView)
self._init()
}

/// Use `override _init` instead of overriding this initializer
public required init?(coder: NSCoder) {
super.init(coder: coder)
self._init()
}

/// Only for `override` purposes, do not call directly
open func _init() {}
}
#endif
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,25 @@ open class CustomNavigationController:
_onDismiss()
}

/// Use `override _init` instead of overriding this initializer
public override init(rootViewController: UIViewController) {
super.init(rootViewController: rootViewController)
self._init()
}

/// Use `override _init` instead of overriding this initializer
public override init(navigationBarClass: AnyClass?, toolbarClass: AnyClass?) {
super.init(navigationBarClass: navigationBarClass, toolbarClass: toolbarClass)
self._init()
}

/// Use `override _init` instead of overriding this initializer
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self._init()
}

/// Use `override _init` instead of overriding this initializer
public required init?(coder: NSCoder) {
super.init(coder: coder)
self._init()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,13 @@ open class CustomTabBarController:
_onDismiss()
}

/// Use `override _init` instead of overriding this initializer
public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self._init()
}

/// Use `override _init` instead of overriding this initializer
public required init?(coder: NSCoder) {
super.init(coder: coder)
self._init()
Expand Down
6 changes: 4 additions & 2 deletions Sources/CocoaExtensions/Macros.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,9 @@ public struct CustomView<ContentView: CocoaView>: CustomReflectable {
extension CocoaViewController {
/// Loads `@CustomView var contentView` to the controller
/// - Returns: `true` if loading succeed, `false` if failed
@_spi(Internals)
@discardableResult
func tryLoadCustomContentView() -> Bool {
public func tryLoadCustomContentView() -> Bool {
let selfMirror = Mirror(reflecting: self)
guard
let _contentView = selfMirror.children
Expand Down Expand Up @@ -228,8 +229,9 @@ public struct CustomWindow<Window: CocoaWindow>: CustomReflectable {
}

extension NSWindowController {
@_spi(Internals)
@discardableResult
func tryLoadCustomWindow() -> Bool {
public func tryLoadCustomWindow() -> Bool {
guard
let _managedWindow = Mirror(reflecting: self).children.first(where: { $0.label == "_managedWindow" })?.value,
let loadWindow = Mirror(reflecting: _managedWindow).children.first(where: { $0.label == "loadWindow" })?.value,
Expand Down

0 comments on commit 8750c34

Please sign in to comment.