自定义 NSWindow 内容边距会导致自动调整大小蒙版混乱
我目前正在使用 this 中显示的方法 Cocoa with Love 文章创建自定义 NSWindow 子类。如示例中所示,我需要在窗口内容周围有大约 10 像素的边距才能绘制箭头(我正在创建一个弹出窗口样式窗口)。我必须在整个窗口周围留有边距,而不仅仅是带有箭头的一侧,因为我希望能够更改箭头位置,而不必重新定位内容。
总而言之,我用来执行此操作的方法是(相关代码在底部):
- 重写 NSWindow 的
contentRectForFrameRect:
和frameRectForContentRect:styleMask:
方法来添加内容周围的填充: - 将窗口的自定义绘制框架视图设置为
contentView
,然后重写contentView
的 setter 和 getter,以便传入的视图添加为框架视图的子视图。
问题在于窗口实际内容视图内的视图的自动调整大小蒙版完全混乱。以下是我在界面生成器中设置内容的方式:
以下是表视图滚动视图的自动调整大小掩码的方式设置为:
以下是如何设置文本标签的自动调整大小掩码:
这是应用程序内的结果:
相关代码(源自上述文章)
#define CONTENT_MARGIN 10.0
- (NSRect)contentRectForFrameRect:(NSRect)windowFrame
{
windowFrame.origin = NSZeroPoint;
return NSInsetRect(windowFrame, CONTENT_MARGIN, ICONTENT_MARGIN);
}
- (NSRect)frameRectForContentRect:(NSRect)contentRect
{
return NSInsetRect(contentRect, -CONTENT_MARGINT, -CONTENT_MARGIN);
}
+ (NSRect)frameRectForContentRect:(NSRect)contentRect
styleMask:(NSUInteger)windowStyle
{
return NSInsetRect(contentRect, -CONTENT_MARGIN, -CONTENT_MARGIN);
}
- (NSView*)contentView
{
return _popoverContentView;
}
- (void)setContentView:(NSView *)aView
{
if ([_popoverContentView isEqualTo:aView]) { return; }
NSRect bounds = [self frame];
bounds.origin = NSZeroPoint;
SearchPopoverWindowFrame *frameView = [super contentView];
if (!frameView) {
frameView = [[[SearchPopoverWindowFrame alloc] initWithFrame:bounds] autorelease];
[super setContentView:frameView];
}
if (_popoverContentView) {
[_popoverContentView removeFromSuperview];
}
_popoverContentView = aView;
[_popoverContentView setFrame:[self contentRectForFrameRect:bounds]];
[_popoverContentView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[frameView addSubview:_popoverContentView];
}
我认为弹出内容可能以某种方式超出了边缘,所以我在内容视图周围画了一个边框,但是没有,一切都是应该如此。唯一的问题是内容视图内标签和表视图的自动调整大小蒙版无法正常工作。非常感谢任何建议。
编辑:如果有人感兴趣,我已经在 github 上开源了这个弹出窗口/控制器的完整代码 INPopoverController。包含一个示例项目,以防您想尝试重现该问题。
I'm currently using the method shown in this Cocoa with Love article to create a custom NSWindow subclass. As in the example, I needed to have a roughly 10px margin around the content of the window in order to draw an arrow (I'm creating a popover style window). I had to have the margin around the entire window instead of just the side with the arrow on it because I wanted to be able to change the arrow position without having to reposition the content.
To summarize, the method I'm using to do this is (relevant code is at the bottom):
- Override the
contentRectForFrameRect:
andframeRectForContentRect:styleMask:
methods of NSWindow to add the padding around the content: - Sets the custom drawn frame view of the window as the
contentView
and then overrides the setter and getter for thecontentView
so that the view that is passed in is added as a subview of the frame view.
The problem is that the autoresizing masks of views inside the actual content view of the window are completely messed up. Here is how I'm setting up the content in interface builder:
Here's how the autoresizing mask of the table view scroll view is set up:
And here's how the text label's autoresizing mask is set:
And here's what the result looks like in-app:
Relevant code (derived from the aforementioned article)
#define CONTENT_MARGIN 10.0
- (NSRect)contentRectForFrameRect:(NSRect)windowFrame
{
windowFrame.origin = NSZeroPoint;
return NSInsetRect(windowFrame, CONTENT_MARGIN, ICONTENT_MARGIN);
}
- (NSRect)frameRectForContentRect:(NSRect)contentRect
{
return NSInsetRect(contentRect, -CONTENT_MARGINT, -CONTENT_MARGIN);
}
+ (NSRect)frameRectForContentRect:(NSRect)contentRect
styleMask:(NSUInteger)windowStyle
{
return NSInsetRect(contentRect, -CONTENT_MARGIN, -CONTENT_MARGIN);
}
- (NSView*)contentView
{
return _popoverContentView;
}
- (void)setContentView:(NSView *)aView
{
if ([_popoverContentView isEqualTo:aView]) { return; }
NSRect bounds = [self frame];
bounds.origin = NSZeroPoint;
SearchPopoverWindowFrame *frameView = [super contentView];
if (!frameView) {
frameView = [[[SearchPopoverWindowFrame alloc] initWithFrame:bounds] autorelease];
[super setContentView:frameView];
}
if (_popoverContentView) {
[_popoverContentView removeFromSuperview];
}
_popoverContentView = aView;
[_popoverContentView setFrame:[self contentRectForFrameRect:bounds]];
[_popoverContentView setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
[frameView addSubview:_popoverContentView];
}
I thought that maybe the popover content was going over the margins somehow, so I drew a border around the content view, but no, everything is as should be. The only issue is that the autoresizing masks of the label and table view inside the content view do not work as they should. Any advice is greatly appreciated.
EDIT: If anyone's interested, I've open-sourced the complete code for this popover window/controller on github as INPopoverController. Includes a sample project in case you want to try and reproduce the issue.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)