Skip to content

Commit

Permalink
Merge branch 'feature/contentview-vb-1' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
helje5 committed Apr 27, 2022
2 parents eb45ee3 + 18c5dba commit 15ea3d3
Show file tree
Hide file tree
Showing 16 changed files with 223 additions and 184 deletions.
84 changes: 35 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,13 @@ More details will be posted but to get started.

class HomePage: ViewController {

struct ContentView: View {

var body: some View {
VStack {
Text("Welcome to MWC!")
.font(.title)
.padding()

Spacer()
}
var view: some View {
VStack {
Text("Welcome to MWC!")
.font(.title)
.padding()

Spacer()
}
}
}
Expand All @@ -58,16 +55,13 @@ More details will be posted but to get started.

class Settings: ViewController {

struct ContentView: View {

var body: some View {
VStack {
Text("Welcome to Settings!")
.font(.title)
.padding()

Spacer()
}
var view: some View { // the View being controlled
VStack {
Text("Welcome to Settings!")
.font(.title)
.padding()

Spacer()
}
}
}
Expand All @@ -82,24 +76,19 @@ More details will be posted but to get started.
show(Settings()) // or `present(Settings())`
}

struct ContentView: View {

@EnvironmentObject private var viewController : HomePage

var body: some View {
VStack {
Text("Welcome to MWC!")
.font(.title)
.padding()

Divider()

Button(action: viewController.configureApp) {
Label("Configure", systemImage: "gear")
}
var view: some View {
VStack {
Text("Welcome to MWC!")
.font(.title)
.padding()

Spacer()
Divider()

Button(action: self.configureApp) {
Label("Configure", systemImage: "gear")
}

Spacer()
}
}
}
Expand Down Expand Up @@ -144,20 +133,17 @@ inline a `NavigationLink`, use `PushLink`, which wraps that.

class HomePage: ViewController {

struct ContentView: View {

var body: some View {
VStack {
Text("Welcome to MWC!")
.font(.title)
.padding()

Divider()
var view: some View {
VStack {
Text("Welcome to MWC!")
.font(.title)
.padding()

PushLink("Open Settings", to: Settings())

Spacer()
}
Divider()

PushLink("Open Settings", to: Settings())

Spacer()
}
}
}
Expand Down
18 changes: 10 additions & 8 deletions Sources/ViewController/AnyViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,20 @@ import SwiftUI
*/
public final class AnyViewController: ViewController {

public var id : ObjectIdentifier { ObjectIdentifier(viewController) }
public var id : ObjectIdentifier { ObjectIdentifier(viewController) }

public let viewController : _ViewController
private var subscription : AnyCancellable?
public let viewController : _ViewController
private var subscription : AnyCancellable?

@usableFromInline
init<VC>(_ viewController: VC) where VC: ViewController {
internal let contentView : () -> AnyView

public init<VC>(_ viewController: VC) where VC: ViewController {
assert(!(viewController is AnyViewController),
"Attempt to nest an AnyVC into another \(viewController)")

self.viewController = viewController
self.contentView = { AnyView(viewController.view) }

subscription = viewController.objectWillChange.sink { [weak self] _ in
self?.objectWillChange.send()
Expand All @@ -54,9 +57,9 @@ public final class AnyViewController: ViewController {
/**
* An initializer that avoids nesting `AnyViewController`s into themselves.
*/
@usableFromInline
init(_ viewController: AnyViewController) {
self.viewController = viewController.viewController
self.contentView = viewController.contentView

// TBD: Can't unwrap this?
subscription = viewController.objectWillChange.sink {
Expand All @@ -70,9 +73,8 @@ public final class AnyViewController: ViewController {
// Those are typed erased by the base protocol already (_ViewController).

@inlinable
public var contentView : AnyView { anyContentView }
@inlinable
public var anyContentView : AnyView { viewController.anyContentView }
@ViewBuilder public var view : AnyView { contentView() }

@inlinable
public var controlledContentView : AnyView { anyControlledContentView }
@inlinable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ open class NavigationController<RootVC>: ViewController, _NavigationController

private func markAsPresentingViewController() {
rootViewController.presentingViewController = self
activePresentations.append(TypedViewControllerPresentation(
activePresentations.append(ViewControllerPresentation(
viewController: _rootViewController,
mode: .custom // not .navigation, that would activate the bg link!
))
Expand All @@ -161,18 +161,11 @@ open class NavigationController<RootVC>: ViewController, _NavigationController

// MARK: - View

public struct ContentView: View {

@EnvironmentObject private var viewController : NavigationController

public init() {}

public var body: some View {
NavigationView {
viewController._rootViewController.contentView
.controlled(by: viewController._rootViewController)
.navigationTitle(viewController._rootViewController.navigationTitle)
}
public var view: some View {
NavigationView {
_rootViewController.view
.controlled(by: _rootViewController)
.navigationTitle(_rootViewController.navigationTitle)
}
}
}
Expand Down
6 changes: 2 additions & 4 deletions Sources/ViewController/MainViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import SwiftUI
* i.e. one which starts a new VC hierarchy.
* Usually only one root VC is used per scene.
*
* Checkout the ``View/main`` modifier for the more general solution.
*
* E.g. this could be used in the `ContentView` of an app like this:
* ```swift
* struct ContentView: View {
Expand Down Expand Up @@ -47,7 +45,7 @@ public struct MainViewController<VC>: View where VC: ViewController {
}

public var body: some View {
VC.ContentView()
.controlled(by: viewController)
viewController
.controlledContentView
}
}
12 changes: 6 additions & 6 deletions Sources/ViewController/NavigationLink/PushLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ import SwiftUI
*
* Content View Example:
* ```swift
* struct ContentView: View {
* var body: some View {
* class HomePage: ViewController {
* var view: some View {
* PushLink("Preferences…", to: PreferencesPage())
* }
* }
* ```
*
* Explicit View Example:
* ```swift
* struct ContentView: View {
* var body: some View {
* class HomePage: ViewController {
* var view: some View {
* PushLink(to: PreferencesPage(), using: Text("Prefs!") {
* Text("Preferences…")
* }
Expand Down Expand Up @@ -200,7 +200,7 @@ public struct PushLink<VC, CV, Label>: View
extension PushLink {

/**
* Create a ``PushLink`` that is using the ``ViewController/ContentView``
* Create a ``PushLink`` that is using the ``ViewController/view``
* as the destination.
*
* Example:
Expand All @@ -221,7 +221,7 @@ extension PushLink {
}

/**
* Create a ``PushLink`` that is using the ``ViewController/ContentView``
* Create a ``PushLink`` that is using the ``ViewController/view``
* as the destination.
*
* Example:
Expand Down
46 changes: 24 additions & 22 deletions Sources/ViewController/Presentations/AutoPresentation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,28 @@ import SwiftUI
struct AutoPresentationViewModifier<VC>: ViewModifier where VC: ViewController {

@ObservedObject var viewController : VC

fileprivate struct Present: View {

@ObservedObject var presentingViewController : VC
let mode : ViewControllerPresentationMode

var body: some View {
if let presentation =
presentingViewController.activePresentation(for: mode)
{
let presentedViewController = presentation.viewController
presentedViewController.anyControlledContentView
.environment(\.viewControllerPresentationMode, mode)
.navigationTitle(presentedViewController.navigationTitle)
}
else {
TypeMismatchInfoView<AnyViewController, VC>(
parent: presentingViewController, expectedMode: mode
)
}
}
}

func body(content: Content) -> some View {
// Note: Also used internally during presentation.
Expand All @@ -27,34 +49,14 @@ struct AutoPresentationViewModifier<VC>: ViewModifier where VC: ViewController {
.sheet(
isPresented: viewController.isPresentingMode(.sheet),
content: {
if let presentation = viewController.activePresentation(for: .sheet) {
presentation.contentView()
.environment(\.viewControllerPresentationMode, .sheet)
.navigationTitle(presentation.viewController.navigationTitle)
}
else {
TypeMismatchInfoView<AnyViewController, VC>(
parent: viewController, expectedMode: .sheet
)
}
Present(presentingViewController: viewController, mode: .sheet)
}
)
.background(
NavigationLink(
isActive: viewController.isPresentingMode(.navigation),
destination: {
if let presentation = viewController
.activePresentation(for: .navigation)
{
presentation.contentView()
.environment(\.viewControllerPresentationMode, .navigation)
.navigationTitle(presentation.viewController.navigationTitle)
}
else {
TypeMismatchInfoView<AnyViewController, VC>(
parent: viewController, expectedMode: .navigation
)
}
Present(presentingViewController: viewController, mode: .navigation)
},
label: { Color.clear } // TBD: EmptyView?
)
Expand Down
12 changes: 10 additions & 2 deletions Sources/ViewController/Presentations/Presentation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,15 @@ public extension _ViewController {
// helpers.
guard !isShowing else {
// isShowing=true would be activation
logger.warning("Attempt to activate VC via Binding, won't work!")
if self.activePresentations.contains(where: { $0.mode == mode }) {
logger.debug(
"Attempt to activate VC via Binding, mode already active!")
}
else {
// FIXME: This can sometimes be seen in sheets, figure out why
logger.warning(
"Attempt to activate VC via Binding, won't work \(self)!")
}
return
}

Expand Down Expand Up @@ -279,7 +287,7 @@ public extension _ViewController {
activePresentation.viewController.dismiss()
}

activePresentations.append(TypedViewControllerPresentation<VC>(
activePresentations.append(ViewControllerPresentation(
viewController: viewController,
mode: mode
))
Expand Down
9 changes: 9 additions & 0 deletions Sources/ViewController/Presentations/PresentationMode.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ import SwiftUI
* ```swift
* public struct ContentView: View {
* @Environment(\.viewControllerPresentationMode) private var mode
*
* var body: some View {
* if mode == .sheet {
* Text("I'm in a sheet!")
* }
* else {
* Text("I'm in a sheet, NOT!")
* }
* }
* }
* ```
*/
Expand Down
Loading

0 comments on commit 15ea3d3

Please sign in to comment.