Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos Can';t更改NSTextField的鼠标光标_Macos_Cocoa_Nstextfield_Nscursor_Nstrackingarea - Fatal编程技术网

Macos Can';t更改NSTextField的鼠标光标

Macos Can';t更改NSTextField的鼠标光标,macos,cocoa,nstextfield,nscursor,nstrackingarea,Macos,Cocoa,Nstextfield,Nscursor,Nstrackingarea,我正在尝试更改窗口工作表中从NIB加载的NSTextField的鼠标光标 在文档之后,我将NSTextField子类化并实现了 这是从来没有被称为。甚至在NSWindowViewController中添加以下内容后也不会: - (void) windowDidLoad { [self.window invalidateCursorRectsForView:self.linkTextField]; } 我还尝试了跟踪区域,在NSTextField子类中添加了以下内容: - (void)

我正在尝试更改窗口工作表中从NIB加载的
NSTextField
的鼠标光标

在文档之后,我将
NSTextField子类化并实现了

这是从来没有被称为。甚至在
NSWindowViewController中添加以下内容后也不会:

- (void) windowDidLoad {
    [self.window invalidateCursorRectsForView:self.linkTextField];
}
我还尝试了跟踪区域,在
NSTextField
子类中添加了以下内容:

- (void) awakeFromNib {
    NSTrackingArea* trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds
                                                 options:(NSTrackingCursorUpdate | NSTrackingActiveAlways)
                                                   owner:self
                                                userInfo:nil];
    [self addTrackingArea:trackingArea];
}

- (void)cursorUpdate:(NSEvent *)theEvent {
    [[NSCursor pointingHandCursor] set];
}

也不管用。我做错了什么?

我也遇到了同样的问题,每次光标进入跟踪区域时都会调用cursorUpdate方法,但光标被放回了其他地方,可能是它的superview

我通过重写mouseMoved方法解决了这个问题

// In the textfield subclass:
- (void)mouseEntered:(NSEvent *)theEvent {
    [super mouseEntered:theEvent];
    self.isMouseIn = YES;
}

- (void)mouseExited:(NSEvent *)theEvent {
    [super mouseExited:theEvent];
    self.isMouseIn = NO;
}


//In the superview of the textfield:
- (void)mouseMoved:(NSEvent *)theEvent {
    if (self.hoverButton.isMouseIn) {
        [[NSCursor pointingHandCursor] set];
    }
    [super mouseMoved:theEvent];
}
我在windowController类中重写了mouseMoved方法,但是重写superview应该可以工作

在子类化
NSTextField
之后,我实现了这一点,如前所述:

- (void)resetCursorRects {
    [self addCursorRect:[self bounds] cursor:[NSCursor pointingHandCursor]];
}

NSTextView似乎通过其
-(void)mouseMoved:(NSEvent*)事件
方法处理光标。另外,当NSTextView成为第一响应程序时,RunLoop中的一些私有代码似乎会将光标强制到IBeamCursor,而不给我们选择的余地。下面是一个子类,它可以绕过这些限制:

@interface MyTextView : NSTextView {
    NSTrackingArea* area;
    BOOL mouseInside;
}

@property(nonatomic, retain) NSTrackingArea* area;

@end


@implementation MyTextView

@synthesize area;

- (void)setArea:(NSTrackingArea *)newArea
{
    [newArea retain];
    if (area) {
        [self removeTrackingArea:area];
        [area release];
    }
    if (newArea) {
        [self addTrackingArea:newArea];
    }
    area = newArea;
}

- (BOOL)becomeFirstResponder
{
    NSRect rect = <insert the tracking rect where you want to have a special cursor>;
    self.area = [[[NSTrackingArea alloc] initWithRect:rect options:NSTrackingMouseEnteredAndExited | NSTrackingActiveWhenFirstResponder owner:self userInfo:nil] autorelease];
    NSEvent* ev = [NSApp currentEvent];
    if (NSPointInRect([self convertPoint:ev.locationInWindow fromView:nil], self.bounds)) {
        mouseInside = YES;
        // This is a workaround for the private call that resets the IBeamCursor
        [[NSCursor arrowCursor] performSelector:@selector(set) withObject:nil afterDelay:0];
    }
}

- (void)mouseEntered:(NSEvent *)theEvent
{
    [super mouseEntered:theEvent];
    [[NSCursor arrowCursor] set];
    mouseInside = YES;
}

- (void)mouseExited:(NSEvent *)theEvent
{
    [super mouseExited:theEvent];
    mouseInside = NO;
}

- (void)mouseMoved:(NSEvent *)theEvent
{
    si (!mouseInside) {
        // We only forward the mouseMoved event when the mouse is outside the zone for which we control the cursor
        [super mouseMoved:theEvent];
    }
}

- (oneway void)dealloc
{
    [area release];
    [super dealloc];
}

@end
@接口MyTextView:NSTextView{
N跟踪区域*区域;
布尔穆塞因赛德;
}
@不动产(非原子,保留)NSTrackingArea*区域;
@结束
@MyTextView的实现
@综合面积;
-(无效)设置区域:(NSTrackingArea*)新建区域
{
[新地区保留];
如果(区域){
[自动跟踪区域:区域];
[区域释放];
}
如果(新区域){
[自添加跟踪区域:新区域];
}
面积=新面积;
}
-(BOOL)成为第一反应者
{
NSRect rect=;
self.area=[[NSTrackingArea alloc]initWithRect:rect选项:NSTrackingMouseentered退出| NSTrackingActiviewhen响应者所有者:self userInfo:nil]autorelease];
NSEvent*ev=[NSApp currentEvent];
if(NSPointInRect([self-convertPoint:ev.locationInWindow fromView:nil],self.bounds])){
mouseInside=是;
//这是重置IBeamCursor的私有调用的一个变通方法
[[NSCursor arrowCursor]性能选择器:@selector(set)with object:nil afterDelay:0];
}
}
-(无效)鼠标输入:(n事件*)事件
{
[超级鼠标:theEvent];
[[NSCursor arrowCursor]set];
mouseInside=是;
}
-(无效)鼠标退出:(n事件*)事件
{
[超级鼠标退出:theEvent];
mouseInside=否;
}
-(无效)鼠标移动:(n事件*)事件
{
si(!mouseInside){
//只有当鼠标位于我们控制光标的区域之外时,我们才转发mouseMoved事件
[超级鼠标移动:theEvent];
}
}
-(单向无效)解除锁定
{
[区域释放];
[super dealoc];
}
@结束

我编写了上述答案的Swift 2.0版,并将其作为

即使是为NSTextField设置的,这些概念也应该适用于
nsrresponder
中的任何子类(这就是
mouseEntered
becomeFirstResponder
的来源)

以下是我编写的代码的精髓:

import Cocoa

class CCTextField: NSTextField {

    var myColorCursor : NSCursor?

    var mouseIn : Bool = false

    var trackingArea : NSTrackingArea?

    override func awakeFromNib()
    {
        myColorCursor = NSCursor.init(image: NSImage(named:"heart")!, hotSpot: NSMakePoint(0.0, 0.0))
    }

    override func resetCursorRects() {
        if let colorCursor = myColorCursor {
            self.addCursorRect(self.bounds, cursor: colorCursor)
        }
    }

    override func mouseEntered(theEvent: NSEvent) {
        super.mouseEntered(theEvent)
        self.mouseIn = true
    }

    override func mouseExited(theEvent: NSEvent) {
        super.mouseExited(theEvent)
        self.mouseIn = false
    }

    override func mouseMoved(theEvent: NSEvent) {
        if self.mouseIn {
            myColorCursor?.set()
        }
        super.mouseMoved(theEvent)
    }

    func setArea(areaToSet: NSTrackingArea?)
    {
        if let formerArea = trackingArea {
            self.removeTrackingArea(formerArea)
        }

        if let newArea = areaToSet {
            self.addTrackingArea(newArea)
        }
        trackingArea = areaToSet
    }

    override func becomeFirstResponder() -> Bool {
        let rect = self.bounds
        let trackingArea = NSTrackingArea.init(rect: rect, options: [NSTrackingAreaOptions.MouseEnteredAndExited, NSTrackingAreaOptions.ActiveAlways], owner: self, userInfo: nil)

        // keep track of where the mouse is within our text field
        self.setArea(trackingArea)

        if let ev = NSApp.currentEvent {
            if NSPointInRect(self.convertPoint(ev.locationInWindow, fromView: nil), self.bounds) {
                self.mouseIn = true
                myColorCursor?.set()
            }
        }
        return true
    }
}
这对我很有用:

class TextField: NSTextField {
    override func becomeFirstResponder() -> Bool {
        addTrackingAreaIfNeeded()
        return super.becomeFirstResponder()
    }
    override func mouseMoved(with event: NSEvent) {
        super.mouseMoved(with: event)
        NSCursor.pointingHand.set()
    }
    private func addTrackingAreaIfNeeded() {
        if trackingAreas.isEmpty {
            let area = NSTrackingArea(rect: bounds, options: [.mouseEnteredAndExited, .activeAlways], owner: self, userInfo: nil)
            addTrackingArea(area)
        }
    }
}

你解决问题了吗?“我也有类似的问题。”詹森:没有。你在尝试不同的方法吗?只是通过在其superview中重写mouseMoved方法来解决这个问题。@Jensen为什么不将其作为答案发布?我试试看。
class TextField: NSTextField {
    override func becomeFirstResponder() -> Bool {
        addTrackingAreaIfNeeded()
        return super.becomeFirstResponder()
    }
    override func mouseMoved(with event: NSEvent) {
        super.mouseMoved(with: event)
        NSCursor.pointingHand.set()
    }
    private func addTrackingAreaIfNeeded() {
        if trackingAreas.isEmpty {
            let area = NSTrackingArea(rect: bounds, options: [.mouseEnteredAndExited, .activeAlways], owner: self, userInfo: nil)
            addTrackingArea(area)
        }
    }
}