Skip to content

Instantly share code, notes, and snippets.

@ericlewis
Last active February 8, 2022 16:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericlewis/eb0a75c7573bb1da554ec920e06f1e6b to your computer and use it in GitHub Desktop.
Save ericlewis/eb0a75c7573bb1da554ec920e06f1e6b to your computer and use it in GitHub Desktop.
PagingView by working with SwiftUI internals. Useful for building "flat" view containers, like a paging view! The paging view itself uses yet another internal type. But serves as a good example for how to build a useful view.
import SwiftUI
struct ContentView: View {
@State
private var show = false
@State
private var selection = 0
var body: some View {
PagingView(page: $selection) {
Color.red.overlay {
VStack(spacing: 15) {
Button("Go next") {
selection = 1
}
Button("Go next animated") {
withAnimation {
selection = 1
}
}
}
}
Color.green.overlay {
Button("Toggle 3rd view.") {
show.toggle()
}
}
if show {
Color.blue
}
}
.ignoresSafeArea()
.tint(.white)
.overlay(alignment: .bottom) {
Text(selection, format: .number)
.frame(maxWidth: .infinity)
.padding()
.background(.thinMaterial)
}
}
}
public struct PagingView<Views: View>: View {
public typealias Config = _PagingViewConfig
public typealias PageIndex = _VariadicView.Children.Index
private let tree: _VariadicView.Tree<Root, Views>
public init(
config: Config = Config(),
page: Binding<PageIndex>? = nil,
@ViewBuilder _ content: () -> Views
) {
tree = _VariadicView.Tree(
Root(
config: config,
page: page
),
content: content
)
}
public var body: some View { tree }
struct Root: _VariadicView.UnaryViewRoot {
let config: Config
let page: Binding<PageIndex>?
func body(children: _VariadicView.Children) -> some View {
_PagingView(
config: config,
page: page,
views: children
)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment