From 574883309d7129eeec76bda605cc52e04bad2c08 Mon Sep 17 00:00:00 2001 From: Kyle Van Essen Date: Tue, 17 Sep 2024 14:34:54 -0700 Subject: [PATCH 1/4] Add passThroughTouches to BlueprintView, PassthroughView. --- .../Sources/BlueprintView/BlueprintView.swift | 28 +++++++++++++++++-- .../Sources/Internal/PassthroughView.swift | 13 +++++++-- CHANGELOG.md | 1 + 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/BlueprintUI/Sources/BlueprintView/BlueprintView.swift b/BlueprintUI/Sources/BlueprintView/BlueprintView.swift index 09959e076..bc4ae1044 100644 --- a/BlueprintUI/Sources/BlueprintView/BlueprintView.swift +++ b/BlueprintUI/Sources/BlueprintView/BlueprintView.swift @@ -118,6 +118,16 @@ public final class BlueprintView: UIView { /// Provides performance metrics about the duration of layouts, updates, etc. public weak var metricsDelegate: BlueprintViewMetricsDelegate? = nil + /// Defaults to `false`. If enabled, Blueprint will pass through any touches + /// not recieved by an element to the view hierarchy behind the `BlueprintView`. + public var passThroughTouches: Bool = false { + didSet { + if oldValue != passThroughTouches { + setNeedsViewHierarchyUpdate() + } + } + } + private var isVisible: Bool = false { didSet { switch (oldValue, isVisible) { @@ -141,7 +151,7 @@ public final class BlueprintView: UIView { rootController = NativeViewController( node: NativeViewNode( - content: UIView.describe { _ in }, + content: PassthroughView.describe { _ in }, // Because no layout update occurs here, passing an empty environment is fine; // the correct environment will be passed during update. environment: .empty, @@ -327,6 +337,18 @@ public final class BlueprintView: UIView { setNeedsViewHierarchyUpdate() } + /// Ignore any touches on this view and (pass through) by returning nil if the default `hitTest` implementation returns this view. + public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + let result = super.hitTest(point, with: event) + + if passThroughTouches { + return result == self ? nil : result + + } else { + return result + } + } + /// Clears any sizing caches, invalidates the `intrinsicContentSize` of the /// view, and marks the view as needing a layout. private func setNeedsViewHierarchyUpdate() { @@ -391,7 +413,9 @@ public final class BlueprintView: UIView { rootController.view.frame = bounds var rootNode = NativeViewNode( - content: UIView.describe { _ in }, + content: PassthroughView.describe { [weak self] config in + config[\.passThroughTouches] = self?.passThroughTouches ?? false + }, environment: environment, layoutAttributes: LayoutAttributes(frame: rootFrame), children: viewNodes diff --git a/BlueprintUI/Sources/Internal/PassthroughView.swift b/BlueprintUI/Sources/Internal/PassthroughView.swift index a791da7e7..4bacd9e7e 100644 --- a/BlueprintUI/Sources/Internal/PassthroughView.swift +++ b/BlueprintUI/Sources/Internal/PassthroughView.swift @@ -8,10 +8,17 @@ import UIKit CATransformLayer.self } - /// Ignore any touches on this view and (pass through) by returning nil if the - /// default `hitTest` implementation returns this view. + public var passThroughTouches: Bool = true + + /// Ignore any touches on this view and (pass through) by returning nil if the default `hitTest` implementation returns this view. public override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { let result = super.hitTest(point, with: event) - return result == self ? nil : result + + if passThroughTouches { + return result == self ? nil : result + + } else { + return result + } } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 80261cc1a..a15368764 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Moved `CornerStyle` out of the `Box` namespace, and is now a root type in `BlueprintUICommonControls`. `Box.CornerStyle` is still available as a typealias. +- `BlueprintView` will now pass through touches to views lower in the view hierarchy if `passThroughTouches` is true. ### Deprecated From 25f66f031f6e1f73a530f924e2559bf7f47a1a76 Mon Sep 17 00:00:00 2001 From: Kyle Van Essen Date: Tue, 17 Sep 2024 16:17:33 -0700 Subject: [PATCH 2/4] Move changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a15368764..7cfcc6131 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,12 +11,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- `BlueprintView` will now pass through touches to views lower in the view hierarchy if `passThroughTouches` is true. + ### Removed ### Changed - Moved `CornerStyle` out of the `Box` namespace, and is now a root type in `BlueprintUICommonControls`. `Box.CornerStyle` is still available as a typealias. -- `BlueprintView` will now pass through touches to views lower in the view hierarchy if `passThroughTouches` is true. ### Deprecated From 9c3f25edac81b1292ab7c71cc31cbbe37006d799 Mon Sep 17 00:00:00 2001 From: Kyle Van Essen Date: Tue, 17 Sep 2024 16:23:40 -0700 Subject: [PATCH 3/4] Fix spacing --- BlueprintUI/Sources/Internal/PassthroughView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/BlueprintUI/Sources/Internal/PassthroughView.swift b/BlueprintUI/Sources/Internal/PassthroughView.swift index 4bacd9e7e..e1cc1162f 100644 --- a/BlueprintUI/Sources/Internal/PassthroughView.swift +++ b/BlueprintUI/Sources/Internal/PassthroughView.swift @@ -16,7 +16,6 @@ import UIKit if passThroughTouches { return result == self ? nil : result - } else { return result } From b48af18b0e2932b1b3264ede042978771d44ac50 Mon Sep 17 00:00:00 2001 From: Kyle Van Essen Date: Tue, 17 Sep 2024 16:24:41 -0700 Subject: [PATCH 4/4] Fix spacing --- BlueprintUI/Sources/BlueprintView/BlueprintView.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/BlueprintUI/Sources/BlueprintView/BlueprintView.swift b/BlueprintUI/Sources/BlueprintView/BlueprintView.swift index bc4ae1044..3b978ed03 100644 --- a/BlueprintUI/Sources/BlueprintView/BlueprintView.swift +++ b/BlueprintUI/Sources/BlueprintView/BlueprintView.swift @@ -343,7 +343,6 @@ public final class BlueprintView: UIView { if passThroughTouches { return result == self ? nil : result - } else { return result }