Skip to content

Commit adff033

Browse files
authored
Merge pull request #26 from p-x9/feature/displaymode
2 parents d5518f9 + 0d99579 commit adff033

File tree

6 files changed

+85
-14
lines changed

6 files changed

+85
-14
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Text("Hello")
2828
.touchPointColor(.orange) // color of mark on touched point
2929
.touchPointBorder(true, color: .blue, width: 1) // applying a border to touched points
3030
.touchPointShadow(true, color: .purple, radius: 3) // shadow on touched points
31+
.touchPointDisplayMode(.recordingOnly) // display mode of touched points
3132
.showLocationLabel(true) // show touch coordinate
3233
```
3334
![Example](https://user-images.githubusercontent.com/50244599/231509731-d3ea5df0-1981-4911-9a14-2b57bf575eb7.PNG)

Sources/TouchTracker/Cocoa/TouchTrackingUIView.swift

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public class TouchTrackingUIView: UIView {
4040
/// A boolean value that indicates whatever adding show coordinates label or not
4141
public var isShowLocation: Bool
4242

43+
/// display mode of touched points.
44+
public var displayMode: DisplayMode
45+
4346

4447
var touches: Set<UITouch> = []
4548
var locations: [CGPoint] = [] {
@@ -67,6 +70,7 @@ public class TouchTrackingUIView: UIView {
6770
/// - shadowOffset: shadow offset of mark on touched point
6871
/// - image: Image to be displayed at the touched point mark
6972
/// - isShowLocation: A boolean value that indicates whatever adding show coordinates label or not
73+
/// - displayMode: display mode of touched points.
7074
public init(
7175
radius: CGFloat = 20,
7276
color: UIColor = .red,
@@ -79,7 +83,8 @@ public class TouchTrackingUIView: UIView {
7983
shadowRadius: CGFloat = 3,
8084
shadowOffset: CGPoint = .zero,
8185
image: UIImage? = nil,
82-
isShowLocation: Bool = false
86+
isShowLocation: Bool = false,
87+
displayMode: DisplayMode = .always
8388
) {
8489
self.radius = radius
8590
self.color = color
@@ -93,6 +98,7 @@ public class TouchTrackingUIView: UIView {
9398
self.shadowOffset = shadowOffset
9499
self.image = image
95100
self.isShowLocation = isShowLocation
101+
self.displayMode = displayMode
96102

97103
super.init(frame: .null)
98104

@@ -160,6 +166,15 @@ public class TouchTrackingUIView: UIView {
160166
}
161167

162168
func updatePoints() {
169+
let isCaptured = window?.screen.isCaptured ?? false
170+
let shouldDisplay = displayMode.shouldDisplay(captured: isCaptured)
171+
172+
if !shouldDisplay {
173+
pointWindows.forEach { $0.isHidden = true }
174+
pointWindows = []
175+
return
176+
}
177+
163178
if pointWindows.count > touches.count {
164179
pointWindows[touches.count..<pointWindows.count].forEach {
165180
$0.isHidden = true
@@ -187,6 +202,8 @@ public class TouchTrackingUIView: UIView {
187202
}
188203
}
189204

205+
let locations = touches.map { $0.location(in: nil) }
206+
190207
zip(pointWindows, locations).forEach { window, location in
191208
window.location = location
192209
window.center = .init(x: location.x + offset.x,
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//
2+
// DisplayMode.swift
3+
//
4+
//
5+
// Created by p-x9 on 2023/08/23.
6+
//
7+
//
8+
9+
#if canImport(UIKit)
10+
import UIKit
11+
#endif
12+
13+
public enum DisplayMode {
14+
case always
15+
case debugOnly
16+
case recordingOnly
17+
}
18+
19+
#if canImport(UIKit)
20+
extension DisplayMode {
21+
func shouldDisplay(captured: Bool) -> Bool {
22+
switch self {
23+
case .always:
24+
return true
25+
case .debugOnly:
26+
#if DEBUG
27+
return true
28+
#else
29+
return false
30+
#endif
31+
case .recordingOnly:
32+
return captured
33+
}
34+
}
35+
}
36+
#endif

Sources/TouchTracker/Model/TouchPointStyle.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ public struct TouchPointStyle: Equatable {
3535

3636
/// A boolean value that indicates whatever adding show coordinates label or not
3737
public var isShowLocation: Bool
38+
39+
/// display mode of touched points.
40+
public var displayMode: DisplayMode
3841

3942
/// Initializer
4043
/// - Parameters:
@@ -49,6 +52,7 @@ public struct TouchPointStyle: Equatable {
4952
/// - shadowRadius: shadow radius of mark on touched point
5053
/// - shadowOffset: shadow offset of mark on touched point
5154
/// - isShowLocation: A boolean value that indicates whatever adding show coordinates label or not
55+
/// - displayMode: display mode of touched points.
5256
public init(
5357
radius: CGFloat = 20,
5458
color: Color = .red,
@@ -60,7 +64,8 @@ public struct TouchPointStyle: Equatable {
6064
shadowColor: Color = .black,
6165
shadowRadius: CGFloat = 3,
6266
shadowOffset: CGPoint = .zero,
63-
isShowLocation: Bool = false
67+
isShowLocation: Bool = false,
68+
displayMode: DisplayMode = .always
6469
) {
6570
self.radius = radius
6671
self.color = color
@@ -73,5 +78,6 @@ public struct TouchPointStyle: Equatable {
7378
self.shadowRadius = shadowRadius
7479
self.shadowOffset = shadowOffset
7580
self.isShowLocation = isShowLocation
81+
self.displayMode = displayMode
7682
}
7783
}

Sources/TouchTracker/TouchLocationView.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,39 @@ import UIKit
1313

1414
struct TouchLocationView<Content: View>: UIViewControllerRepresentable {
1515
@Binding var locations: [CGPoint]
16+
@Binding var isCaptured: Bool
1617
let content: () -> Content
1718

18-
init(_ locations: Binding<[CGPoint]>, content: @escaping () -> Content) {
19+
init(_ locations: Binding<[CGPoint]>, isCaptured: Binding<Bool>, content: @escaping () -> Content) {
1920
self._locations = locations
21+
self._isCaptured = isCaptured
2022
self.content = content
2123
}
2224

2325
func makeUIViewController(context: Context) -> some UIViewController {
2426
let controller = TouchLocationWrapView(rootView: content())
25-
controller.touchesChangeHandler = { locations in
27+
controller.touchesChangeHandler = { [weak controller] locations in
2628
self.$locations.wrappedValue = locations
29+
self.$isCaptured.wrappedValue = controller?.isCaptured ?? false
2730
}
2831
return controller
2932
}
3033

3134
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
3235
guard let controller = uiViewController as? TouchLocationWrapView<Content> else { return }
3336
controller.rootView = content()
34-
controller.touchesChangeHandler = { locations in
37+
controller.touchesChangeHandler = { [weak controller] locations in
3538
self.$locations.wrappedValue = locations
39+
self.$isCaptured.wrappedValue = controller?.isCaptured ?? false
3640
}
3741
}
3842

3943
}
4044

4145
class TouchLocationWrapView<Content: View>: UIHostingController<Content> {
4246
var touchesChangeHandler: (([CGPoint]) -> Void)?
43-
44-
var touches: Set<UITouch> = []
45-
var locations: [CGPoint] = [] {
46-
didSet {
47-
touchesChangeHandler?(locations)
48-
}
47+
var isCaptured: Bool {
48+
view.window?.screen.isCaptured ?? false
4949
}
5050

5151
lazy var trackLocationUIView: TouchLocationCocoaView = {

Sources/TouchTracker/TouchTracker.swift

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public struct TouchTrackingView<Content: View>: View {
99
let content: Content
1010

1111
@State var locations: [CGPoint] = []
12+
@State var isCaptured: Bool = false
1213

1314
var radius: CGFloat = 20
1415
var color: Color = .red
@@ -28,6 +29,8 @@ public struct TouchTrackingView<Content: View>: View {
2829

2930
var isShowLocation: Bool = false
3031

32+
var displayMode: DisplayMode = .always
33+
3134
public init(_ content: Content) {
3235
self.content = content
3336
#if canImport(UIKit)
@@ -68,11 +71,13 @@ public struct TouchTrackingView<Content: View>: View {
6871
.hidden()
6972
.background(
7073
ZStack {
71-
TouchLocationView($locations) {
74+
TouchLocationView($locations, isCaptured: $isCaptured) {
7275
content
7376
}
74-
touchPointsView
75-
.zIndex(.infinity)
77+
if displayMode.shouldDisplay(captured: isCaptured){
78+
touchPointsView
79+
.zIndex(.infinity)
80+
}
7681
}
7782
)
7883
#endif
@@ -124,6 +129,11 @@ extension TouchTrackingView {
124129
set(enabled, for: \.isShowLocation)
125130
}
126131

132+
/// display mode of touched points.
133+
public func touchPointDisplayMode(_ mode: DisplayMode) -> Self {
134+
set(mode, for: \.displayMode)
135+
}
136+
127137
public func setTouchPointStyle(_ style: TouchPointStyle) -> Self {
128138
self
129139
.set(style.radius, for: \.radius)
@@ -137,6 +147,7 @@ extension TouchTrackingView {
137147
.set(style.shadowRadius, for: \.shadowRadius)
138148
.set(style.shadowOffset, for: \.shadowOffset)
139149
.set(style.isShowLocation, for: \.isShowLocation)
150+
.set(style.displayMode, for: \.displayMode)
140151
}
141152

142153
private func set<T>(_ value: T, for keyPath: WritableKeyPath<TouchTrackingView, T>) -> Self {

0 commit comments

Comments
 (0)