如何在 Xamarin.Mac 的 NSView 中检测调整大小?

How to detect resize in NSView in Xamarin.Mac?

检测 NSView 何时调整大小的正确方法是什么?。 我没有看到视图上有任何可用的调整大小事件或视图的任何委托。

我已经添加了这个 hack,我在其中使用 drawRect 来检测大小的变化,但我确信必须有更正确的方法来做到这一点。

    CGRect m_resizeRect = CGRect.Empty;
    public override void DrawRect(CGRect dirtyRect)
    {
        base.DrawRect(dirtyRect);
        if (this.InLiveResize) {
            if (m_resizeRect.Size != this.Bounds.Size) {
                m_resizeRect = this.Bounds;
                this.OnResize();
            }
        }
    }
    public override void ViewWillStartLiveResize()
    {
        m_resizeRect = this.Bounds;
        base.ViewWillStartLiveResize();
    }
    public override void ViewDidEndLiveResize()
    {
        m_resizeRect = CGRect.Empty;
        base.ViewDidEndLiveResize();
    }
    protected void OnResize() {
        Console.WriteLine("OnResize " + this.Bounds.ToString() );
    }

查看 NSView postsBoundsChangedNotifications and postFrameChangedNotifications 属性。您可以设置这些并注册这些通知。

您可以订阅调整大小通知。

将观察者添加到默认通知中心:

NSObject NSWindowDidResizeNotificationObject;
public override void ViewDidLoad ()
{
    base.ViewDidLoad ();
    NSWindowDidResizeNotificationObject = NSNotificationCenter.DefaultCenter.AddObserver (new NSString ("NSWindowDidResizeNotification"), ResizeObserver, null);
}

NSNotification 操作:

public void ResizeObserver (NSNotification notify)
{
    var r = this.View.Frame;
    Console.WriteLine ("{0}:{1}:{1}", notify.Name, r.Height, r.Width);
}

移除观察者(并释放内存):

NSNotificationCenter.DefaultCenter.RemoveObserver (NSWindowDidResizeNotificationObject);

示例输出:

NSWindowDidResizeNotification:740:740
NSWindowDidResizeNotification:715:715
NSWindowDidResizeNotification:681:681
NSWindowDidResizeNotification:642:642

您可以覆盖 setFrameSize 方法并在每次更新框架时执行您自己的操作。

class MyView: NSView {
    ...
    override func setFrameSize(newSize: NSSize) {
        super.setFrameSize(newSize)
        Swift.print("new size is \(frame)")
    }
    ...
}

接受的答案似乎只响应 window 尺寸变化,而不是例如当 splitview 的拆分条导致调整大小时。

您可以使用 NSViewController.viewDidLayout() 覆盖方法:

class MyViewController: NSViewController {
    ...
    override func viewDidLayout() {
        Swift.print("view has been resize to \(self.view.frame)")
    }
    ...
}