我需要一个更大的滚动窗口内的固定大小的NSTextViews.IB要求textviews位于他们自己的NSScrollViews中,即使他们的最小/最大大小是固定的,以便它们实际上不会滚动.当在textview框架内制作触控板手势时(无论它们是否具有焦点),它们都会被textview的scrollview捕获,因此没有任何反应.
如何告诉textviews的scrollview将滚动事件传递到窗口的主滚动视图?(或许我应该问我如何告诉窗口的主滚动视图本身处理这些事件,而不是将它们传递给它的子滚动视图.)
IB结构是这样的:
我在侦听事件时遇到问题,我可以听取完美运行的事件但是我不能让它停止听事件.我研究了一段时间,想出了一个方法,+(void)removeMonitor:(id)eventMonitor,它说当我完成监听器时我应该使用它
但是当我尝试使用这种方法时,就像这样
[NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDownMask|NSKeyDownMask) handler:^(NSEvent *event) {
[NSEvent removeMonitor:event];
}];
Run Code Online (Sandbox Code Playgroud)
我一直收到错误" - [NSEvent invalidate]:无法识别的选择器发送到实例"我也研究过,我相信这意味着我正在覆盖正在使用的内存.但是我不知道如何解决这个问题.任何建议或帮助非常感谢!
更新感谢JWWalker,Samir和Abizern,它现在有效
//I made a global variable called eventHAndler
Run Code Online (Sandbox Code Playgroud)
.h文件
id eventHAndler
Run Code Online (Sandbox Code Playgroud)
.m文件
eventHAndler = [NSEvent addGlobalMonitorForEventsMatchingMask:(NSLeftMouseDownMask|NSKeyDownMask) handler:^(NSEvent *event){
///code
}];
/// created another method called stop. When called it stops the eventHAndler
- (IBAction)Stop:(id)sender
{
stop = 1;
NSLog(@"inside stop method");
[NSEvent removeMonitor:eventHAndler];
}
Run Code Online (Sandbox Code Playgroud) 在我的应用程序中,我希望滚动发生,只有鼠标滚轮动作而不是触控板上的两个手指动作.基本上,我试图确定是否从鼠标或触控板生成scrollWheelEvent,内部 - (void)scrollWheel:(NSEvent*)theEvent方法.据我所知,到目前为止,似乎没有直接的方法来实现这一目标.
我尝试了将boolean变量设置为true和false in - (void)beginGestureWithEvent:(NSEvent*)event; 和 - (void)endGestureWithEvent:(NSEvent*)事件; 但这不是一个解决方案,因为在调用endGestureWithEvent:方法之后,会多次调用scrollWheel:方法.
这是我的代码:
$BOOL fromTrackPad = NO;
-(void)beginGestureWithEvent:(NSEvent *)event;
{
fromTrackPad = YES;
}
-(void) endGestureWithEvent:(NSEvent *)event;
{
fromTrackPad = NO;
}
- (void)scrollWheel:(NSEvent *)theEvent
{
if(!fromTrackPad)
{
//then do scrolling
}
else
{
//then don't scroll
}
}
Run Code Online (Sandbox Code Playgroud)
我知道这是不标准的,但这是我的要求.有谁知道这样做的方法?谢谢!
NSEvent keyCode提供键盘扫描代码,这是代表物理密钥的硬件特定代码.我想将扫描代码转换为虚拟键代码,这是基于用户键盘布局(QWERTY,AZERTY等)的逻辑键.
在Windows中,我可以通过MapVirtualKey完成此操作.什么是OS X等价物?
我正在尝试复制iTunes中搜索字段的行为,以查找股票代码和名称.具体来说,当您开始在搜索字段中键入时,会显示带有过滤项的弹出窗口.在大多数情况下,我有这个工作,但我无法复制的是它处理第一响应者的方式
输入三个字符后,我出现了弹出窗口.此时,NSSearchField将失去第一响应者状态,因此我无法继续键入.我想要的行为是能够在弹出窗口后继续键入,如果使用箭头键滚动项目,然后继续键入,您将从搜索字段中的最后一个字符继续.
我尝试的是子类化NSTextView(使用它作为NSSearchField的自定义字段编辑器)和覆盖
- (BOOL)resignFirstResponder
Run Code Online (Sandbox Code Playgroud)
通过简单地返回NO,我可以在弹出框出现后继续输入,但显然我无法选择弹出窗口中的任何项目.所以我尝试了以下操作,如果出现向下箭头或mousedown事件,则返回YES.
@interface SBCustomFieldEditor ()
{
BOOL resignFirstRepond;
}
@end
@implementation SBCustomFieldEditor
- (id)initWithFrame:(NSRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
resignFirstRepond = NO;
}
return self;
}
- (BOOL)resignFirstResponder
{
return resignFirstRepond;
}
- (void)keyDown:(NSEvent *)theEvent
{
if ([theEvent keyCode] == 125) {
resignFirstRepond = YES;
[self resignFirstResponder];
}
[super keyDown:theEvent];
}
- (void)mouseDown:(NSEvent *)theEvent
{
resignFirstRepond = YES;
[self resignFirstResponder];
}
Run Code Online (Sandbox Code Playgroud)
这适用于mousedown事件,但不适用于keydown事件,此外,当用户恢复键入时,这不能解决问题.
有什么建议?
我有兴趣在NSMenu打开时捕获按键.例如,如果菜单是开放的,用户按下"E",或"1"在键盘上,发送特定的消息(优选地通过压制成哪个键的事件对象包含参考).
我看着备用菜单,但我只能被用来捕捉选项键的印象是.
目前我没有使用任何自定义视图,只是NSStatusBar(菜单产生的地方)和NSMenu.
我是Objective-C的新手,所以如果我的措辞不正确,我会道歉.
真的很感激帮助!
我有一个NSView,它涵盖了它的父窗口的内容视图.此视图具有单击事件处理程序,可将其从内容视图中删除.在这个视图中,我有另一种观点.当我在此内部视图中拖动鼠标时,鼠标事件不仅应用于前面的视图,还应用于后面的视图.此外,背后视图中的游标也会出现.这是同样的问题:NSView overlay将鼠标事件传递给基础子视图?但那里的答案对我的项目不起作用,因为我无法打开另一个窗口.
谢谢.
我正在尝试模拟 Spotlight 在 Yosemite 中的工作方式,其中 NSTextField(搜索字段)在按下向上/向下箭头键并上下移动表格视图选择时始终保持焦点。
\n\n我已经实现了以下代码:
\n\n- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)commandSelector\n{\n if (commandSelector == @selector(moveUp:)) {\n // move up\n return YES;\n } else if(commandSelector == @selector(moveDown:)){\n // move down\n return YES;\n }\n\n return NO;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n虽然我可以使用它来向上/向下移动行选择,例如:
\n\n[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:currentRow \xc2\xb1 1] byExtendingSelection:NO];\nRun Code Online (Sandbox Code Playgroud)\n\n我遇到的问题是我创建了不应选择的节标题行,并且我已使用 NSTableViewDelegate 方法禁用了对这些行的选择:
\n\n- (BOOL)tableView: (NSTableView *)tableView shouldSelectRow: (NSInteger)row\nRun Code Online (Sandbox Code Playgroud)\n\n但发生的情况是selectRowIndexes:indexSetWithIndex:currentRowbyExtendingSelection:即使委托方法表明无法选择该行,该方法也会选择标题行。
无论 NSTableViewDelegate 说什么,您似乎仍然可以以编程方式选择行。我想要的是选择跳过标题行。
\n\n如果 NSTableView 是firstResponder则内置键盘控件会跳过标题行。
所以我的问题是有没有办法将向上/向下事件转发到 NSTableView 以便移动选择的内置机制起作用?
\n我一直在尝试(从事件处理程序中)确定哪个键盘触发了该事件。我一直在使用这两篇文章:
在第二篇文章中,作者使用Carbon技术成功地分离了键盘,但是使用Cocoa尝试相同的技巧失败了。
在我自己的系统上,两者都失败了,可能是因为我的无线键盘也是苹果制造的,所以可能报告的标识符与内置键盘相同。
在第一篇文章中,有人提出了一种解决方案,该方案在较低级别(可以区分键盘)上监视键盘事件,并将此数据存储在队列中,然后让事件处理程序检索信息。
这看起来有些毛茸茸,所以我只是在这里检查是否有人发现了更好的东西。
这是我的代码,展示了在事件处理程序中区分键盘的失败:
// compile and run from the commandline with:
// clang -fobjc-arc -framework Cocoa -framework Carbon ./tap_k.m -o tap_k
// sudo ./tap_k
#import <Foundation/Foundation.h>
#import <AppKit/NSEvent.h>
//#import <CarbonEventsCore.h>
#include <Carbon/Carbon.h>
typedef CFMachPortRef EventTap;
// - - - - - - - - - - - - - - - - - - - - -
@interface KeyChanger : NSObject
{
@private
EventTap _eventTap;
CFRunLoopSourceRef _runLoopSource;
CGEventRef _lastEvent;
}
@end
// - - - …Run Code Online (Sandbox Code Playgroud) 我目前正在开发一个适用于 iOS 和 macOS 的跨平台应用程序,使您的 iOS 设备充当触控板。
使用CGDisplayMoveCursorToPoint,我可以在屏幕上移动光标。奇迹般有效。通过“主机”应用程序(即在 macOS 上运行)中的这段代码,我可以单击鼠标:
let currentPosition = foo() // call to my helper function
// that translates NSEvent.mouseLocation()
let downEvent = CGEvent(
mouseEventSource: nil,
mouseType: .leftMouseDown,
mouseCursorPosition: currentPosition,
mouseButton: .left
)
let upEvent = CGEvent(
mouseEventSource: nil,
mouseType: .leftMouseUp,
mouseCursorPosition: currentPosition,
mouseButton: .left
)
downEvent?.post(tap: CGEventTapLocation.cghidEventTap)
upEvent?.post(tap: CGEventTapLocation.cghidEventTap)
Run Code Online (Sandbox Code Playgroud)
到目前为止,一切都很好。
现在我想在iOS设备上用两根手指实现滚动。问题不在于 iOS 和 macOS 之间的通信(顺便说一句,PeerTalk 很棒),而是我似乎无法在主机上触发滚动事件。
起初,我尝试了这样的事情:
let eventSource = CGEventSource(stateID: .hidSystemState)
let event = CGEvent(
mouseEventSource: eventSource,
mouseType: .scrollWheel,
mouseCursorPosition: currentPosition,
mouseButton: …Run Code Online (Sandbox Code Playgroud) nsevent ×10
cocoa ×8
macos ×3
objective-c ×2
iokit ×1
keyboard ×1
nsmenu ×1
nspopover ×1
nsresponder ×1
nsscrollview ×1
nstableview ×1
nsview ×1
trackpad ×1