Created
June 14, 2021 21:02
-
-
Save tyirvine/93ee7b4d6f44ee333cdfc5f419f11389 to your computer and use it in GitHub Desktop.
This registers clicks on a view in SwiftUI even when the window is not key or main
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// InactiveWindowTapHelper.swift | |
// | |
// Created by Ty Irvine on 2021-06-14. | |
// | |
// This registers clicks on a view in SwiftUI even when the window is not key or main. | |
// | |
// Usage ⤵︎ | |
/* | |
Text("Hello world!") | |
.inactiveWindowTap { pressed in | |
print(pressed) | |
} | |
*/ | |
import Foundation | |
import SwiftUI | |
extension View { | |
func inactiveWindowTap(_ pressed: @escaping (Bool) -> Void) -> some View { | |
modifier(InactiveWindowTapModifier(pressed)) | |
} | |
} | |
struct InactiveWindowTapModifier: ViewModifier { | |
let pressed: (Bool) -> Void | |
init(_ pressed: @escaping (Bool) -> Void) { | |
self.pressed = pressed | |
} | |
func body(content: Content) -> some View { | |
content.overlay( | |
GeometryReader { proxy in | |
ClickableViewRepresentable( | |
pressed: pressed, | |
frame: proxy.frame(in: .global) | |
) | |
} | |
) | |
} | |
} | |
private struct ClickableViewRepresentable: NSViewRepresentable { | |
let pressed: (Bool) -> Void | |
let frame: NSRect | |
func updateNSView(_ nsView: ClickableView, context: Context) { | |
nsView.pressed = pressed | |
} | |
func makeNSView(context: Context) -> ClickableView { | |
ClickableView(frame: frame, pressed: pressed) | |
} | |
} | |
class ClickableView: NSView { | |
public var pressed: ((Bool) -> Void)? | |
init(frame: NSRect, pressed: ((Bool) -> Void)?) { | |
super.init(frame: frame) | |
self.pressed = pressed | |
} | |
@available(*, unavailable) | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
override func acceptsFirstMouse(for event: NSEvent?) -> Bool { | |
return true | |
} | |
override func mouseDown(with event: NSEvent) { | |
pressed?(true) | |
} | |
override func mouseUp(with event: NSEvent) { | |
pressed?(false) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment