Merge pull request #736 from cdoncarroll/cdoncarroll-VisibleWindowTouches
Add Debug Option For Displaying Touches
This commit is contained in:
commit
da3f631380
|
@ -22,5 +22,13 @@ extension UIApplication {
|
|||
|
||||
return version == build ? "v\(version)" : "v\(version) (\(build))"
|
||||
}
|
||||
|
||||
func getKeyWindow() -> UIWindow? {
|
||||
return UIApplication
|
||||
.shared
|
||||
.connectedScenes
|
||||
.flatMap { ($0 as? UIWindowScene)?.windows ?? [] }
|
||||
.first { $0.isKeyWindow }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -122,6 +122,10 @@ extension HomeTimelineViewController {
|
|||
identifier: nil,
|
||||
options: [],
|
||||
children: [
|
||||
UIAction(title: "Toggle Visible Touches", image: UIImage(systemName: "hand.tap"), attributes: []) { _ in
|
||||
guard let window = UIApplication.shared.getKeyWindow() as? TouchesVisibleWindow else { return }
|
||||
window.touchesVisible = !window.touchesVisible
|
||||
},
|
||||
UIAction(title: "Toggle EmptyView", image: UIImage(systemName: "clear"), attributes: []) { [weak self] action in
|
||||
guard let self = self else { return }
|
||||
if self.emptyView.superview != nil {
|
||||
|
|
|
@ -11,6 +11,7 @@ import Combine
|
|||
import CoreDataStack
|
||||
import MastodonCore
|
||||
import MastodonExtension
|
||||
import MastodonUI
|
||||
|
||||
#if PROFILE
|
||||
import FPSIndicator
|
||||
|
@ -35,8 +36,13 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
|
||||
guard let windowScene = scene as? UIWindowScene else { return }
|
||||
|
||||
#if DEBUG
|
||||
let window = TouchesVisibleWindow(windowScene: windowScene)
|
||||
self.window = window
|
||||
#else
|
||||
let window = UIWindow(windowScene: windowScene)
|
||||
self.window = window
|
||||
#endif
|
||||
|
||||
// set tint color
|
||||
window.tintColor = UIColor.label
|
||||
|
|
|
@ -0,0 +1,135 @@
|
|||
//
|
||||
// TouchesVisibleWindow.swift
|
||||
//
|
||||
//
|
||||
// Created by Chase Carroll on 12/5/22.
|
||||
//
|
||||
|
||||
#if DEBUG
|
||||
|
||||
import UIKit
|
||||
|
||||
/// View that represents a single touch from the user.
|
||||
private final class TouchView: UIView {
|
||||
|
||||
private let blurView = UIVisualEffectView(effect: nil)
|
||||
|
||||
override var frame: CGRect {
|
||||
didSet {
|
||||
layer.cornerRadius = frame.height / 2.0
|
||||
}
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
let isLightMode = traitCollection.userInterfaceStyle == .light
|
||||
|
||||
backgroundColor = .clear
|
||||
layer.masksToBounds = true
|
||||
layer.cornerCurve = .circular
|
||||
layer.borderColor = isLightMode ? UIColor.gray.cgColor : UIColor.white.cgColor
|
||||
layer.borderWidth = 2.0
|
||||
|
||||
let blurEffect = isLightMode ?
|
||||
UIBlurEffect(style: .systemUltraThinMaterialDark) :
|
||||
UIBlurEffect(style: .systemUltraThinMaterialLight)
|
||||
blurView.effect = blurEffect
|
||||
addSubview(blurView)
|
||||
}
|
||||
|
||||
@available(iOS, unavailable)
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
blurView.frame = bounds
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// `UIWindow` subclass that renders visual representations of the user's touches.
|
||||
public final class TouchesVisibleWindow: UIWindow {
|
||||
|
||||
public var touchesVisible = false {
|
||||
didSet {
|
||||
if !touchesVisible {
|
||||
cleanUpAllTouches()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var touchViews: [UITouch : TouchView] = [:]
|
||||
|
||||
private func newTouchView() -> TouchView {
|
||||
let touchSize = 44.0
|
||||
return TouchView(frame: CGRect(
|
||||
origin: .zero,
|
||||
size: CGSize(
|
||||
width: touchSize,
|
||||
height: touchSize
|
||||
)
|
||||
))
|
||||
}
|
||||
|
||||
private func cleanupTouch(_ touch: UITouch) {
|
||||
guard let touchView = touchViews[touch] else {
|
||||
return
|
||||
}
|
||||
|
||||
touchView.removeFromSuperview()
|
||||
touchViews.removeValue(forKey: touch)
|
||||
}
|
||||
|
||||
private func cleanUpAllTouches() {
|
||||
for (_, touchView) in touchViews {
|
||||
touchView.removeFromSuperview()
|
||||
}
|
||||
|
||||
touchViews.removeAll()
|
||||
}
|
||||
|
||||
public override func sendEvent(_ event: UIEvent) {
|
||||
if touchesVisible {
|
||||
let touches = event.allTouches
|
||||
|
||||
guard
|
||||
let touches = touches,
|
||||
touches.count > 0
|
||||
else {
|
||||
cleanUpAllTouches()
|
||||
super.sendEvent(event)
|
||||
return
|
||||
}
|
||||
|
||||
for touch in touches {
|
||||
let touchLocation = touch.location(in: self)
|
||||
switch touch.phase {
|
||||
case .began:
|
||||
let touchView = newTouchView()
|
||||
touchView.center = touchLocation
|
||||
addSubview(touchView)
|
||||
touchViews[touch] = touchView
|
||||
|
||||
case .moved:
|
||||
if let touchView = touchViews[touch] {
|
||||
touchView.center = touchLocation
|
||||
}
|
||||
|
||||
case .ended, .cancelled:
|
||||
cleanupTouch(touch)
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.sendEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue