Cocoa NSView frame通过-setFrame以外的方式设置:自动调整大小后

Cocoa NSView frame通过-setFrame以外的方式设置:自动调整大小后,cocoa,nsview,autoresizingmask,Cocoa,Nsview,Autoresizingmask,我的应用程序通过NSWindowController从XIB文件加载窗口和窗口内的按钮。在-windowDidLoad中,我根据窗口的大小以编程方式设置按钮的框架,窗口的大小可以根据可见的按钮而变化)。在XIB中为这些按钮适当设置自动调整大小的遮罩。问题是,当窗口实际出现时,按钮似乎没有应用自动调整大小 在调试这个问题时,我在调用super的-setFrame:后,将NSButton子类化并重写-setFrame:以打印帧([self frame])。使用此方法,我观察到框架设置了两次:首先是通

我的应用程序通过
NSWindowController
从XIB文件加载窗口和窗口内的按钮。在
-windowDidLoad
中,我根据窗口的大小以编程方式设置按钮的框架,窗口的大小可以根据可见的按钮而变化)。在XIB中为这些按钮适当设置自动调整大小的遮罩。问题是,当窗口实际出现时,按钮似乎没有应用自动调整大小

在调试这个问题时,我在调用super的
-setFrame:
后,将
NSButton子类化并重写
-setFrame:
以打印帧(
[self frame]
)。使用此方法,我观察到框架设置了两次:首先是通过编程布局代码(称为框架A),然后是Cocoa根据用户偏好调整窗口大小(应用自动调整大小掩码,将框架设置为B)。这些框架看起来都是正确的

但是,当窗口出现时,就好像后一个
-setFrame:
调用没有持久的效果-按钮的帧现在返回到A。这可以通过中断调试器并打印帧来验证-自动调整帧更新已恢复,但从未再次调用
-setFrame:


关于我为什么会看到这种行为,有什么想法吗?

superview
通过
setFrameSize:
调整大小时,它首先会发生,但更常见的情况是调用
superview
layoutSubtreeIfNeeded
方法,该方法反过来调用视图的
resizeWithOldSuperviewSize:
。您可以通过子类化
NSView
(在本例中为
NSButton
)并使用空方法覆盖
resizeWithOldSuperviewSize:
)来覆盖此项

- (void)resizeWithOldSuperviewSize:(NSSize)oldSize {}
但是,您也可以通过声明不希望自动布局系统调整
NSView
的大小来更优雅地解决问题。您可以通过以下方式完成此操作:

[<id> setAutoresizingMask:NSViewNotSizable];
[<id> setTranslatesAutoresizingMaskIntoConstraints:YES];
然后你就可以开始了

[self.myButton setAutoresizingMask:NSViewNotSizable];
[self.myButton setTranslatesAutoresizingMaskIntoConstraints:YES];
然后使用所需的帧调用
setFrame:
。第一行表示视图不可缩放,而第二行表示遮罩应被自动布局系统视为约束。希望有帮助

编辑:
抱歉,由于某种原因,我认为您的问题与我的建议相反,即自动布局正在覆盖您的更改。然而,你想知道的恰恰相反。如果您使用的是
setAutoresizingMask:
您是否尝试过
setTranslatesAutoresizingMaskIntoConstraints:YES
?如果您可以发布一个最小的工作示例,这也会很有帮助。

superview
通过
setFrameSize:
调整大小时,最初会发生这种情况,但在调用
superview
layoutSubtreeifneed
方法时,这种情况更常见,它依次调用视图的
resizeWithOldSuperviewSize:
。您可以通过子类化
NSView
(在本例中为
NSButton
)并使用空方法覆盖
resizeWithOldSuperviewSize:
)来覆盖此项

- (void)resizeWithOldSuperviewSize:(NSSize)oldSize {}
但是,您也可以通过声明不希望自动布局系统调整
NSView
的大小来更优雅地解决问题。您可以通过以下方式完成此操作:

[<id> setAutoresizingMask:NSViewNotSizable];
[<id> setTranslatesAutoresizingMaskIntoConstraints:YES];
然后你就可以开始了

[self.myButton setAutoresizingMask:NSViewNotSizable];
[self.myButton setTranslatesAutoresizingMaskIntoConstraints:YES];
然后使用所需的帧调用
setFrame:
。第一行表示视图不可缩放,而第二行表示遮罩应被自动布局系统视为约束。希望有帮助

编辑: 抱歉,由于某种原因,我认为您的问题与我的建议相反,即自动布局正在覆盖您的更改。然而,你想知道的恰恰相反。如果您使用的是
setAutoresizingMask:
您是否尝试过
setTranslatesAutoresizingMaskIntoConstraints:YES
?如果您能发布一个简单的工作示例,这也会很有帮助