【问题标题】:mouseEntered and mouseExited not called in NSImageView SubClassNSImageView 子类中未调用 mouseEntered 和 mouseExited
【发布时间】:2012-06-26 15:09:41
【问题描述】:

我创建了NSImageView 的子类来捕获mouseEnteredmouseExited 事件。 但只有mouseUpmouseDown 事件被调用。如何捕获NSImageView子类中的mouseEnteredmouseExited事件?

【问题讨论】:

    标签: objective-c macos cocoa nsimageview


    【解决方案1】:

    如果你想使用mouseEntered:mouseExited:你需要使用NSTrackingArea。这是参考NSTrackingArea Class Reference

    示例:

    //Add this to Your imageView subclass
    
    -(void)mouseEntered:(NSEvent *)theEvent {
        NSLog(@"Mouse entered");
    }
    
    -(void)mouseExited:(NSEvent *)theEvent
    {
        NSLog(@"Mouse exited");
    }
    
    -(void)updateTrackingAreas
    { 
        [super updateTrackingAreas];
        if(trackingArea != nil) {
            [self removeTrackingArea:trackingArea];
            [trackingArea release];
        }
    
        int opts = (NSTrackingMouseEnteredAndExited | NSTrackingActiveAlways);
        trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
                                                     options:opts
                                                       owner:self
                                                    userInfo:nil];
        [self addTrackingArea:trackingArea];
    }
    

    【讨论】:

    • @ArtOfWarfare 或者,当用户只是将指针滑过一大块 UI 时,它具有复杂的视图层次结构并且不想调用潜在的数十万个方法,这就是现实。这是古老的永远不要投票,永远拉动。
    • @Edward 什么?拉动与民意调查?不;与 1988 年相比,2016 年的相关性显着。在 1988 年,所有设备都由墙壁供电。 2016 年,大多数设备由电池供电,轮询对电池寿命造成毁灭性影响。
    • @bbum 刚刚意识到你在母舰工作。我鞠躬。
    • “当用户只是滑动指针时调用成百上千的方法”?如果没有定义回调函数,有什么可以调用的? C# 对所有控件都有完全相同的回调,您不必设置奇怪的内部 sn-ps 代码,隐藏在文档的色调中。如果您为控件定义了回调,它将被调用,否则什么都没有。就如此容易。我不明白 OS X 堆栈有什么不同之处需要这样做。
    • @RicardoAnjos updateTrackingAreas 通常适合此操作。例如,如果这是在较早的某个地方(例如在 init 中),则在移动或调整视图大小时不会正确地重新创建它。
    【解决方案2】:

    Swift 4 版本的Justin Boo's answer

    override func updateTrackingAreas() {
        super.updateTrackingAreas()
    
        for trackingArea in self.trackingAreas {
            self.removeTrackingArea(trackingArea)
        }
        
        let options: NSTrackingArea.Options = [.mouseEnteredAndExited, .activeAlways]
        let trackingArea = NSTrackingArea(rect: self.bounds, options: options, owner: self, userInfo: nil)
        self.addTrackingArea(trackingArea)
    }
    

    【讨论】:

    • 我们可以/应该不编辑现有答案以将其更新为最新版本的语言吗?
    【解决方案3】:

    Swift 3 版本@Justin Boo的回答:

    private var trackingArea: NSTrackingArea?
    
    override func updateTrackingAreas() {
        super.updateTrackingAreas()
    
        if let trackingArea = self.trackingArea {
            self.removeTrackingArea(trackingArea)
        }
    
        let options: NSTrackingAreaOptions = [.mouseEnteredAndExited, .activeAlways]
        let trackingArea = NSTrackingArea(rect: self.bounds, options: options, owner: self, userInfo: nil)
        self.addTrackingArea(trackingArea)
    }
    

    【讨论】:

    • 为什么 super 没有被调用?它在贾斯汀的解决方案中
    • @CharltonProvatas,你是对的,这是一个错误。官方文档还说应该调用它。我的答案现已更新。
    【解决方案4】:

    Justin Boo 的答案的 C# Xamarin 版本

    public override void UpdateTrackingAreas ()
    {
        base.UpdateTrackingAreas ();
    
        foreach (var item in TrackingAreas ()) {
            RemoveTrackingArea (item);
        }
    
        var options = NSTrackingAreaOptions.MouseEnteredAndExited | NSTrackingAreaOptions.ActiveAlways;
    
        var trackingArea = new NSTrackingArea (this.Bounds, options, this, null);
    
        AddTrackingArea (trackingArea);
    }
    

    【讨论】:

      猜你喜欢
      • 2014-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 1970-01-01
      • 2010-12-18
      • 2014-01-31
      • 1970-01-01
      相关资源
      最近更新 更多