首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何观察NSNotification在SwiftUI macOS项目中按下修饰符键(例如选项、移位)?

如何观察NSNotification在SwiftUI macOS项目中按下修饰符键(例如选项、移位)?
EN

Stack Overflow用户
提问于 2022-12-02 16:19:25
回答 2查看 28关注 0票数 0

我想要一个Bool属性,它表示按下@Publised var isOptionPressed = false的选项键。我会用它来改变SwiftUI视图。

为此,我认为,我应该使用联合观察的关键压力。

我试图为该事件找到一个NSNotification,但在我看来,似乎没有任何NSNotification,这对我是有用的。

EN

Stack Overflow用户

回答已采纳

发布于 2022-12-03 04:59:38

由于您正在使用SwiftUI,所以我建议您在查看发布者并将修饰符标志的状态放入SwiftUI Environment之后,再向前迈出一步。我认为它将很好地符合SwiftUI的声明性语法。

我有另一个实现,但采用了您找到的解决方案,并对其进行了调整。

代码语言:javascript
运行
复制
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内容更改为:

代码语言:javascript
运行
复制
struct KeyWatcherApp: App {
    var body: some Scene {
        WindowGroup {
            ModifierFlagEnvironment {
                ContentView()
            }
        }
    }
}

因此,应用程序中的所有视图都可以查看这些标志。

那么,为了利用它,您可以:

代码语言:javascript
运行
复制
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视图监视标志的环境,视图决定使用当前修饰符显示什么。

票数 0
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74658685

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档