如何在 iOS 13 Objective-c 中处理鼠标事件

Posted

技术标签:

【中文标题】如何在 iOS 13 Objective-c 中处理鼠标事件【英文标题】:How to handle mouse events in iOS 13 objective-c 【发布时间】:2019-09-22 01:39:21 【问题描述】:

ios 13 终于引入了对鼠标的支持。我一直在徒劳地寻找有关如何处理鼠标事件的文档。在 macOS 10+ 中有 NSEvent 类 https://developer.apple.com/documentation/appkit/nsevent 作为 AppKit 的一部分。 iOS 13 中对应的类是什么?有人可以指点我一些文档/示例吗?我已经尝试过https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/EventOverview/HandlingMouseEvents/HandlingMouseEvents.html 中的代码,但它在 iOS 13 中不起作用。我使用的是 Xcode 11。我对获取鼠标事件信息(例如,pressedMouseButtons、mouseLocation、buttonNumber)特别感兴趣。

- (void)mouseDown:(NSEvent *)theEvent 
    [self setFrameColor:[NSColor redColor]];
    [self setNeedsDisplay:YES];

- (void)mouseUp:(NSEvent *)theEvent 
    [self setFrameColor:[NSColor greenColor]];
    [self setNeedsDisplay:YES];

【问题讨论】:

【参考方案1】:

此功能似乎没有公共 API。

对于您想要的一些内容,从 iPadOS 13.4 开始!

iOS 13 上的所有“鼠标”事件都注册为常规触摸事件,只是 像 AssistiveTouch 产生的事件。您无法检查 这些事件的来源。

这是正确的。让我们深入研究...

背景和链接

在 iPad 上,从 iPadOS 13.4 开始,支持触控板和鼠标没有启用任何辅助功能。请注意,iPhone 没有获得这种原生支持。我在下面讨论的 API 仍然适用,但仅适用于启用了对 AssistiveTouch 的指点设备支持的 iPhone。

我们在这里查看事件和手势 API: https://developer.apple.com/videos/play/wwdc2020/10094/

如果您在开发者应用中查看该视频,则包含视频中的代码 sn-ps。

我在下面描述的一些兼容模式可供性在此处进行了详细说明: https://developer.apple.com/documentation/bundleresources/information_property_list/uiapplicationsupportsindirectinputevents

(编辑) GameController.framework 确实显示了我在下面提到的所有连接的鼠标,您可以为每个鼠标设置更改处理程序。但是,那里无法查看这些设备的 ID:

https://developer.apple.com/documentation/gamecontroller/gcmouse/3626182-mice https://developer.apple.com/videos/play/wwdc2020/10617/

指针移动和点击

指针移动由UIEvent.EventType.hover 驱动。您可以使用 UIHoverGestureRecognizer 处理。

指针设备上的点击被转换为UITouch 实例。作为兼容性提供,默认情况下这些都是UITouch.TouchType.direct。这与基于手指的触摸相同。

如果您在应用程序的 info.plist 键中选择了 UIApplicationSupportsIndirectInputEvents,则对指针设备的点击将转换为 UITouch.TouchType.indirectPointer。这将使您能够将这些触摸与基于手指的触摸区分开来,并且您可以使用UIGestureRecognizer.allowedTouchTypes 之类的 API 专门针对这些触摸。

按钮掩码

使用 UIApplicationSupportsIndirectInputEvents,您将能够识别来自定点设备的触摸发生。要识别特定按钮,您需要查看UIEvent.buttonMaskUIGestureRecognizer.buttonMask。请注意,UIGestureRecognizer 的属性来自最后处理的事件。

.buttonMask 将向您显示在活动期间按下的一组按钮。

结论

据我了解,您希望完成以下任务:

    识别来自定点设备的点击 确定按下了哪个按钮 确定点击来自哪个设备。

对于#1,您可以使用 UIApplicationSupportsIndirectInputEvents 来获取新的UITouch.TouchType.indirectPointer,这将使您能够区分这些触摸。

对于#2,您可以在UIEventUIGestureRecognizer 上使用.buttonMask

对于#3,目前在 iOS 上没有 API 来实现这一点。

(编辑) 一位同事提到 GameController.framework 可能会对此有所帮助。

https://developer.apple.com/documentation/gamecontroller

您将能够看到所有使用GCMouse.mice() 连接的鼠标,并在它们连接时收到通知:

https://developer.apple.com/documentation/gamecontroller/gcmouse/3626182-mice

很遗憾,您也无法在此处看到鼠标的 ID。尽管如此,它还是给了你一些需要考虑的东西。

观看此视频,了解更多有关 GameController.framework 对指点设备和键盘的支持的详细信息:

https://developer.apple.com/videos/play/wwdc2020/10617/

【讨论】:

感谢@moseley 的详细回复。我尝试使用视频中显示的代码 sn-ps 和所提供文档中的定义,并且还有两个问题:1)GCMouse 定义在哪里?它似乎不是 GameConrtoller.framework 的一部分 我如何访问这个类? import GCMouse 给我一个错误:没有这样的模块'GCMouse'。我将 GameController.framework 添加到我的项目中,但没有 GCMouse 框架:-) 2) 有没有办法以编程方式将指针位置设置为某些屏幕坐标,比如屏幕中心? 我的错误:我忽略了 GCMouse 仅在 iOS 14.0+ 和 macOS 11.0+ 中可用,而我目前使用的是 iOS 13.5.1 和 macOS 10.15.5【参考方案2】:

此功能似乎没有公共 API。

iOS 13 上的所有“鼠标”事件都注册为常规触摸事件,就像 AssistiveTouch 产生的事件一样。您无法检查这些事件的来源。

注意:这是一个辅助功能,您不应该依赖它被启用,并且无法检测它是否已启用或强制用户启用它。

【讨论】:

感谢您富有洞察力的回复。没有公共 API 有点令人失望,尤其是没有办法检查事件的来源。我的应用程序旨在串联使用两只鼠标,获取源 ID 至关重要。有人可以建议一个可能的解决方法吗?至于这是一个辅助功能这一事实,我假设我总是可以预先要求用户启用它。有什么问题吗?!? 我能够使用 UITouch 和 UIEvent 获得“鼠标”事件,但触摸和事件的描述中没有任何内容可以提供有关事件来源的信息。我需要确定的是:1)被点击的鼠标的ID。 2)单击了哪个鼠标按钮(左或右)。关于如何实现这一点的任何建议? @ValNenov 无法检查导致所述事件的鼠标。至于按钮,我相信这取决于用户如何设置自己的按钮,并且可能因设备而异。 我想知道 Apple iOS 13 开发团队中是否有人正在阅读这些帖子?!?很高兴收到他们的回复。在 android 9 API 28 上可以轻松访问此功能。 我发布这个问题已经一个多月了,到目前为止还没有令人满意的答案。我怎样才能说服 Apple iOS 13 开发团队考虑将这个无缝的基本功能添加到 iOS 13 API?即: 1) 获取被点击的鼠标ID,尤其是同时连接多只鼠标时。 2)单击了哪个鼠标按钮(左或右) - UP 和 DOWN 事件。我已通过官方在线渠道将此建议发送给 Apple,但没有回复。有什么建议吗?

以上是关于如何在 iOS 13 Objective-c 中处理鼠标事件的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 13 [UIApplication sharedApplication] delegate].window 中使用objective-c 不起作用

Xcode 11.4 和 iOS 13.4 打破了 Project 中的 Objective-C 类别

iOS Objective-C:如何从另一个类调用 Push Segue

Xcode 11.4 Objective-C 语言的快速帮助,而不是 swift 语言,用于带有 Cocoapods 的 firebase API(iOS 13.4 应用程序)

Objective-C(13)代码块---block

Objective-C(13)代码块---block