Refactor `.introspect` to use `ViewModifier` (#253)

This commit is contained in:
David Roman 2023-06-10 19:50:56 +01:00 committed by GitHub
parent 80356a6b96
commit d7b1d71ee3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 36 additions and 19 deletions

View File

@ -12,33 +12,50 @@ public struct IntrospectionScope: OptionSet {
}
extension View {
@ViewBuilder
public func introspect<SwiftUIViewType: IntrospectableViewType, PlatformSpecificEntity: PlatformEntity>(
_ viewType: SwiftUIViewType,
on platforms: (PlatformViewVersions<SwiftUIViewType, PlatformSpecificEntity>)...,
scope: IntrospectionScope? = nil,
customize: @escaping (PlatformSpecificEntity) -> Void
) -> some View {
self.modifier(IntrospectModifier(viewType, platforms: platforms, scope: scope, customize: customize))
}
}
struct IntrospectModifier<SwiftUIViewType: IntrospectableViewType, PlatformSpecificEntity: PlatformEntity>: ViewModifier {
let id = IntrospectionViewID()
let scope: IntrospectionScope
let selector: IntrospectionSelector<PlatformSpecificEntity>?
let customize: (PlatformSpecificEntity) -> Void
init(
_ viewType: SwiftUIViewType,
platforms: [PlatformViewVersions<SwiftUIViewType, PlatformSpecificEntity>],
scope: IntrospectionScope?,
customize: @escaping (PlatformSpecificEntity) -> Void
) {
self.scope = scope ?? viewType.scope
if let platform = platforms.first(where: \.isCurrent) {
let introspectionViewID = IntrospectionViewID()
self.background(
IntrospectionAnchorView(
id: introspectionViewID
)
self.selector = platform.selector ?? .default
} else {
self.selector = nil
}
self.customize = customize
}
func body(content: Content) -> some View {
if let selector {
content
.background(
IntrospectionAnchorView(id: id)
.frame(width: 0, height: 0)
)
.overlay(
IntrospectionView(
id: introspectionViewID,
selector: { controller in
(platform.selector ?? .default)(controller, scope ?? viewType.scope)
},
customize: customize
)
IntrospectionView(id: id, selector: { selector($0, scope) }, customize: customize)
.frame(width: 0, height: 0)
)
} else {
self
content
}
}
}