-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support modifying parameters in multiple previews (#40)
Resolves #14 This allows for consumers to override parameters in previews by using `Exhibit.preview(parameters: [String: Any]) -> some View` This allows for multiple previews to be had for easing development. In order to support the passing of parameters in this way, some refactoring was required: `Exhibit` is now a strict model, not a view itself, allowing it to be generic and more easily understood. `AnyExhibit` is added which is a type-erased version for use in arrays, and then `AnyExhibitView` displays the actual exhibit with support for context observing. For some reason, a compiler error unfortunately occurs in the preview definition if `layout` is left as a closure on `Exhibit`. The only solution I could find which left types intact is to move the layout override to a separate function in the `Exhibit` protocol.
- Loading branch information
Malcolm Jarvis
authored
Mar 4, 2022
1 parent
128890e
commit e193122
Showing
10 changed files
with
136 additions
and
83 deletions.
There are no files selected for viewing
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
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
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
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
72 changes: 37 additions & 35 deletions
72
Sources/Exhibition/Exhibit.Context.swift → Sources/Exhibition/Context.swift
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,65 @@ | ||
import SwiftUI | ||
|
||
public struct Exhibit: View { | ||
public struct Exhibit<Content: View> { | ||
|
||
let name: String | ||
let section: String | ||
let view: (Context) -> AnyView | ||
let layout: (Self) -> AnyView | ||
|
||
@ObservedObject var context = Context() | ||
let content: (Context) -> Content | ||
|
||
public init<T: View, S: View>( | ||
public init( | ||
name: String, | ||
section: String = "", | ||
@ViewBuilder builder: @escaping (Context) -> T, | ||
@ViewBuilder layout: @escaping (Self) -> S | ||
@ViewBuilder builder: @escaping (Context) -> Content | ||
) { | ||
self.name = name | ||
self.section = section | ||
view = { context in AnyView(builder(context)) } | ||
self.layout = { exhibit in AnyView(layout(exhibit)) } | ||
self.content = builder | ||
} | ||
} | ||
|
||
extension Exhibit { | ||
@ViewBuilder public func preview(parameters: [String: Any] = [:]) -> some View { | ||
ExhibitView( | ||
exhibit: self, | ||
context: Context(parameters: parameters) | ||
) | ||
} | ||
} | ||
|
||
struct ExhibitView<Content: View>: View { | ||
let exhibit: Exhibit<Content> | ||
@ObservedObject var context: Context | ||
|
||
var body: some View { | ||
exhibit.content(context) | ||
} | ||
} | ||
|
||
public struct AnyExhibit { | ||
let name: String | ||
let section: String | ||
let content: (Context) -> AnyView | ||
|
||
public var body: some View { | ||
view(context) | ||
.navigationTitle(name) | ||
init<Content: View, Layout: View>(_ exhibit: Exhibit<Content>, layout: @escaping (Content) -> Layout) { | ||
self.name = exhibit.name | ||
self.section = exhibit.section | ||
self.content = { context in | ||
AnyView(layout(exhibit.content(context))) | ||
} | ||
} | ||
} | ||
|
||
extension Exhibit: Identifiable { | ||
extension AnyExhibit: Identifiable { | ||
public var id: String { | ||
name | ||
} | ||
} | ||
|
||
extension Exhibit { | ||
public init<T: View>( | ||
name: String, | ||
section: String = "", | ||
@ViewBuilder builder: @escaping (Context) -> T | ||
) { | ||
self.init( | ||
name: name, | ||
section: section, | ||
builder: builder | ||
) { AnyView($0) } | ||
struct AnyExhibitView: View { | ||
let exhibit: AnyExhibit | ||
@ObservedObject var context: Context | ||
|
||
var body: some View { | ||
exhibit.content(context) | ||
} | ||
} |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,28 @@ | ||
import SwiftUI | ||
|
||
public protocol ExhibitProvider { | ||
static var exhibit: Exhibit { get } | ||
associatedtype Content: View | ||
associatedtype Layout: View | ||
|
||
static var exhibit: Exhibit<Content> { get } | ||
|
||
static func exhibitLayout(_ content: Content) -> Layout | ||
} | ||
|
||
public extension ExhibitProvider { | ||
static var previews: some View { | ||
exhibit | ||
.preview() | ||
.previewLayout(.sizeThatFits) | ||
} | ||
|
||
static var anyExhibit: AnyExhibit { | ||
AnyExhibit(exhibit, layout: exhibitLayout) | ||
} | ||
} | ||
|
||
public extension ExhibitProvider where Content == Layout { | ||
static func exhibitLayout(_ content: Content) -> Layout { | ||
content | ||
} | ||
} |
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