5

NSTextFieldNIB から読み込まれたウィンドウ シートのマウス カーソルを変更しようとしています。

ドキュメントに従って、サブクラス化NSTextFieldして実装しresetCursorRectsました。

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

これは決して呼び出されません。に以下を追加した後でも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];
}

どちらも機能しませんでした。私は何を間違っていますか?

4

5 に答える 5

7

NSTextField を使用したクリック可能なリンク

前述のようにサブクラス化した後、これを機能させましたNSTextField

- (void)resetCursorRects {
    [self addCursorRect:[self bounds] cursor:[NSCursor pointingHandCursor]];
}
于 2013-09-04T11:03:43.293 に答える
2

NSTextView は、その-(void)mouseMoved:(NSEvent*)theEventメソッドを通じてカーソルを処理しているようです。また、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
于 2014-02-06T16:03:55.377 に答える
1

私は同じ問題を抱えていました。カーソルが追跡領域に入るたびにcursorUpdateメソッドが呼び出されましたが、カーソルは別の場所、おそらくそのスーパービューに戻されました。

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 メソッドをオーバーライドしましたが、スーパービューのオーバーライドは機能するはずです。

于 2013-04-06T16:50:06.687 に答える