我想要一个Bool属性,它表示按下@Publised var isOptionPressed = false的选项键。我会用它来改变SwiftUI视图。
为此,我认为,我应该使用联合观察的关键压力。
我试图为该事件找到一个NSNotification,但在我看来,似乎没有任何NSNotification,这对我是有用的。
发布于 2022-12-03 04:59:38
由于您正在使用SwiftUI,所以我建议您在查看发布者并将修饰符标志的状态放入SwiftUI Environment之后,再向前迈出一步。我认为它将很好地符合SwiftUI的声明性语法。
我有另一个实现,但采用了您找到的解决方案,并对其进行了调整。
import Cocoa
import SwiftUI
import Combine
struct KeyModifierFlags: EnvironmentKey {
static let defaultValue = NSEvent.ModifierFlags([])
}
extension EnvironmentValues {
var keyModifierFlags: NSEvent.ModifierFlags {
get { self[KeyModifierFlags.self] }
set { self[KeyModifierFlags.self] = newValue }
}
}
struct ModifierFlagEnvironment<Content>: View where Content:View {
@StateObject var flagState = ModifierFlags()
let content: Content;
init(@ViewBuilder content: () -> Content) {
self.content = content();
}
var body: some View {
content
.environment(\.keyModifierFlags, flagState.modifierFlags)
}
}
final class ModifierFlags: ObservableObject {
@Published var modifierFlags = NSEvent.ModifierFlags([])
init() {
NSEvent.addLocalMonitorForEvents(matching: .flagsChanged) { [weak self] event in
self?.modifierFlags = event.modifierFlags
return event;
}
}
}注意,我的事件闭包返回传入的事件。如果您返回nil,您将阻止事件发生得更远,并且系统中的其他人可能希望看到它。
struct KeyModifierFlags设置要添加到视图Environment中的新项。对EnvironmentValues的扩展允许我们从环境中存储和检索当前的标志。
最后是ModifierFlagEnvironment视图。它没有自己的内容--传递给@ViewBuilder函数中的初始化器。它所做的是提供包含状态监视器的StateObject,并将修饰符标志的当前值传递给内容的Environment。
若要使用ModifierFlagEnvironment,请将层次结构中的顶层视图与其一起包装。在一个由默认Xcode模板构建的简单Cocoa应用程序中,我将应用程序SwiftUI内容更改为:
struct KeyWatcherApp: App {
var body: some Scene {
WindowGroup {
ModifierFlagEnvironment {
ContentView()
}
}
}
}因此,应用程序中的所有视图都可以查看这些标志。
那么,为了利用它,您可以:
struct ContentView: View {
@Environment(\.keyModifierFlags) var modifierFlags: NSEvent.ModifierFlags
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
if(modifierFlags.contains(.option)) {
Text("Option is pressed")
} else {
Text("Option is up")
}
}
.padding()
}
}在这里,content视图监视标志的环境,视图决定使用当前修饰符显示什么。
https://stackoverflow.com/questions/74658685
复制相似问题