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 { extension View {
@ViewBuilder
public func introspect<SwiftUIViewType: IntrospectableViewType, PlatformSpecificEntity: PlatformEntity>( public func introspect<SwiftUIViewType: IntrospectableViewType, PlatformSpecificEntity: PlatformEntity>(
_ viewType: SwiftUIViewType, _ viewType: SwiftUIViewType,
on platforms: (PlatformViewVersions<SwiftUIViewType, PlatformSpecificEntity>)..., on platforms: (PlatformViewVersions<SwiftUIViewType, PlatformSpecificEntity>)...,
scope: IntrospectionScope? = nil, scope: IntrospectionScope? = nil,
customize: @escaping (PlatformSpecificEntity) -> Void customize: @escaping (PlatformSpecificEntity) -> Void
) -> some View { ) -> 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) { if let platform = platforms.first(where: \.isCurrent) {
let introspectionViewID = IntrospectionViewID() self.selector = platform.selector ?? .default
self.background( } else {
IntrospectionAnchorView( self.selector = nil
id: introspectionViewID }
) self.customize = customize
}
func body(content: Content) -> some View {
if let selector {
content
.background(
IntrospectionAnchorView(id: id)
.frame(width: 0, height: 0) .frame(width: 0, height: 0)
) )
.overlay( .overlay(
IntrospectionView( IntrospectionView(id: id, selector: { selector($0, scope) }, customize: customize)
id: introspectionViewID,
selector: { controller in
(platform.selector ?? .default)(controller, scope ?? viewType.scope)
},
customize: customize
)
.frame(width: 0, height: 0) .frame(width: 0, height: 0)
) )
} else { } else {
self content
} }
} }
} }