根据NSOutlineView高度动态调整NSWindow [英] Dynamically resize NSWindow based on NSOutlineView height

查看:591
本文介绍了根据NSOutlineView高度动态调整NSWindow的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了很多关于动态调整NSWindows的大小的问题的答案。



我已经构建了一个popover菜单栏,我不能使用NSPopover,因为它在设计方面不够定制。我的视图层次结构当前是这样的:

  NSWindow子类
- NSView(清除标题栏渲染,绘制popover箭头)
- NSView(contentView)
- NSOutlineView(主要内容)
- NSView(窗口页脚)

我需要的是扩展和收缩NSOutlineView扩展和收缩项目的窗口,所以窗口总是精确地为大纲视图,页脚和弹出框的正确高度



我有基于内容计算大纲视图所需高度的方法。到目前为止,我一直在尝试在内容视图控制器上调用 awakeFromNib 时重新计算大小,然后再次调用委托方法 outlineViewItemDidCollapse: outlineViewItemDidExpand:,但我无法正确调整窗口大小。



尝试了很多不同的方式,没有工作。有没有一个规范的方式来做到这一点?我已经看到人们谈论关于这种问题的 - [NSWindow frameForContentRect:] ,但我不能完全找出需要如何。



也许我会完全错误的方式,我希望不是。似乎这应该是可能的,它只是得到正确的东西在正确的地方。不幸的是,GUI编程对我来说不是一个强点。



编辑:

>这解决了,部分是由于标记的答案,部分是由于一些其他的东西。清除NSView没有自动调整大小掩码,所以我设置这在所有方向扩展,这有助于一些调整大小问题。此外,我用于计算所需的高度的方法不完全正确,有几个问题。



根据提供的答案,找到所需高度的方法适用于某些情况,但我没有可以衡量的根项目。

解决方案

这里是我的方法,它工作得很好,但有可能比这更好。

   - (void)outlineViewItemDidExpand:(NSNotification *)notification {
[self resizeWindowHeight];
}
- (void)outlineViewItemDidCollapse:(NSNotification *)notification {
[self resizeWindowHeight];
}
- (void)resizeWindowHeight {
NSRect wRect = [myWindow frame];
NSRect oRect = [myoutlineView rectOfRow:([myoutlineView numberOfRows] - 1)]; // get rect of last row
CGFloat n = oRect.origin.y + oRect.size.height + 22;
wRect.origin.y = wRect.origin.y +(wRect.size.height - n);
wRect.size.height = n;
[myWindow setFrame:wRect display:YES animate:YES];
}

数字 22 顶部窗口 - 顶部轮廓)+轮廓标题的高度+水平滚轮的高度+(底部窗口 - 底部轮廓)+工具栏的高度



对于此示例:没有水平滚动条和标题,高度Outline =窗口的contentView的高度,因此22是窗口边框。



你有一个工具栏或水平滚动条被自动隐藏,你需要在代码中添加条件来检查(工具栏和滚动条)的可见性,并相应地改变高度。


I have read many answers to questions about dynamically resizing NSWindows and nothing has quite worked yet.

I have built a 'popover' like window to be displayed form the menu bar, I couldn't use NSPopover because it isn't quite customisable enough in terms of design. My view hierarchy current looks like this:

NSWindow Subclass
  - NSView (clears the titlebar rendering, draws popover arrow)
     - NSView (contentView)
        - NSOutlineView (main table of content)
        - NSView (window footer)

What I need is for the window to expand and contract with items in the NSOutlineView expanding and contracting, so that the window is always precisely the correct height for the outline view, footer, and the popover arrow at the top.

I have methods to calculate the required height for the outline view based on the content. So far I have been trying to recalculate the size when awakeFromNib is called on the content view controller, and then again on the delegate methods outlineViewItemDidCollapse: and outlineViewItemDidExpand:, but I am never able to resize the window correctly.

I have tried lots of different ways and none worked. Is there a 'canonical' way to do this? I've seen people talking about -[NSWindow frameForContentRect:] in relation to this sort of problem, but I can't quite work out how that is needed.

Maybe I am going about this completely the wrong way, I hope not though. It seems like this should be possible, it's just getting the right things in the right places. Unfortunately GUI programming is not a strong point for me. I would appreciate any ideas or solutions people have.

Thanks.

Edit: This was solved, partly due to the marked answer, and partly due to a few other things. The clearing NSView did not have an autoresize mask, so I set this to expand in all directions, this helped with some of the resizing issues. Also, the method I was using for calculating the height required was not entirely correct and had a few problems.

With the provided answer, the way to find the required height is good for some circumstances, but I didn't have a 'root' item that could be measured. This is something that may need to be taken into account.

解决方案

Here is my method, it works very well, but there are probably better than that.

- (void)outlineViewItemDidExpand:(NSNotification *)notification {
    [self resizeWindowHeight];
}
- (void)outlineViewItemDidCollapse:(NSNotification *)notification {
    [self resizeWindowHeight];
}
- (void)resizeWindowHeight {
    NSRect wRect = [myWindow frame];
    NSRect oRect = [myoutlineView rectOfRow:([myoutlineView numberOfRows] - 1)]; //get rect of last row
    CGFloat n = oRect.origin.y + oRect.size.height + 22;
    wRect.origin.y = wRect.origin.y + (wRect.size.height - n);
    wRect.size.height = n;
    [myWindow setFrame:wRect display:YES animate:YES];
}

The number 22 is the sum of : (top window - top Outline) + height of Outline header + height of horizontal scroller + (bottom window - bottom Outline) + height of toolbar

My settings in IB for this example : no horizontal scroller and no header , height of Outline = height of the contentView of the window, so 22 is the window border.

If you have a toolbar or the horizontal scroller is hidden automatically, you need to add conditions in the code to check the visibility of (the toolbar and scroller) and change the height accordingly.

这篇关于根据NSOutlineView高度动态调整NSWindow的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆