NSScrollView 滚动条的长度错误

发布于 12-23 15:02 字数 325 浏览 4 评论 0原文

我有一个 Cocoa 窗口,其内容视图包含一个 NSScrollView,而 NSScrollView 又包含一个固定大小的 NSView。

启动程序后,最初显示的滚动条太小,就好像内容大小比实际大小大得多:

当我开始使用垂直滚动条并将其带回顶部的原始位置时,它会调整到预期大小(对应于滚动视图和内容视图大小的比率 ):

在此处输入图像描述

(请注意水平条,其尺寸仍然不正确。如果我随后使用它,并将其带回到它最左边的位置,它被调整到正确的大小。)

I have a Cocoa window, whose content view contains an NSScrollView that, in turns, contains a fixed-size NSView.

Upon launching the program, the scroll bars displayed initially are too small, as if the content size was much larger than it actually is:

enter image description here

When I start playing with, e.g., the vertical scroll bar, and bring it back to the original position at the top, it gets resized to its expected size (which corresponds to the ratio of scroll view and content view sizes):

enter image description here

(Notice the horizontal bar, which still has incorrect size. If I then play with it, and bring it back to its leftmost position, it gets resized to the correct size.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

断爱2024-12-30 15:02:00

我也遇到了同样的问题,我到处搜索过,但似乎没有人遇到这个问题。幸运的是我找到了解决这个问题的 hack。

我注意到的是,当调整窗口大小或最大化时,滚动条会调整到预期大小(必须启用自动调整大小)。这是因为当窗口大小调整时,滚动视图和滚动条的长度也会重新计算并正确计算。可能由于某些错误,初始化时无法正确计算滚动条长度。无论如何,要解决该问题,请在应用程序委托中创建一个到窗口的出口。重写“applicationDidFinishLaunching”方法,并在其内部调用窗口出口上的“frame”方法,该方法返回窗口当前的 NSRect。使用返回值将 size.width 和 size.height 加一。调用 setFrame 方法并将显示设置为 YES。这将调整窗口大小并强制重新计算滚动条的大小。

下面是 applicationDidFinishLaunching 的代码

(void)applicationDidFinishLaunching:(NSNotification *)aNotification
{

     // Get the current rect
     NSRect windowRect = [_window frame];`

     // add one to the width and height to resize window
     windowRect.size.width += 1;
     windowRect.size.height += 1;

     // resize window with display:YES to redraw window subviews
     [_window setFrame:windowSize display:YES];

}

I also encountered the same problem, I have searched everywhere but it seems no one else experiences this problem. Fortunately I found a hack which solves the problem.

What I did notice was that when the window is resized or maximized the scrollbars resize to the expected size (autoresizing has to be enabled). This is because when the window resizes so does the scrollview and the length of the scroll bars gets recalculated and is calculated correctly. Possibly due to some bug the scroll bar lengths are not calculated correctly on initialization. Anyway to fix the problem, in your application delegate create an outlet to your window. Override the "applicationDidFinishLaunching" method and inside it call the method "frame" on the window outlet, which returns the current NSRect of the window. Using the returned value add one to the size.width and size.height. The call the method setFrame with display set to YES. This will resize the window and force the size of the scrollbars to be recalculated.

Here is the code for applicationDidFinishLaunching Below

(void)applicationDidFinishLaunching:(NSNotification *)aNotification
{

     // Get the current rect
     NSRect windowRect = [_window frame];`

     // add one to the width and height to resize window
     windowRect.size.width += 1;
     windowRect.size.height += 1;

     // resize window with display:YES to redraw window subviews
     [_window setFrame:windowSize display:YES];

}
私藏温柔2024-12-30 15:02:00

我在修改 NSTextView textContainer 大小以切换换行时遇到此问题。调整封闭视图的大小确实会导致使用正确的滚动视图高度,但这是一个残酷的解决方案。

NSScrollView 支持 -reflectScrolledClipView。在我的例子中直接调用它没有任何效果,除非在运行循环上延迟:

[textScrollView performSelector:@selector(reflectScrolledClipView:) withObject:textScrollView.contentView afterDelay:0];

滚动条位置是正确的,但有滚动条重画。所以看起来好像视图几何的一部分是在绘图时计算的。因此,更好的解决方案是:

NSDisableScreenUpdates();
[textScrollView display];
[textScrollView reflectScrolledClipView:textScrollView.contentView];
[textScrollView display];
NSEnableScreenUpdates();

I encountered this issue when modifying an NSTextView textContainer size to toggle line wrapping. Resizing the enclosing view does cause the correct scroll view height to be used, however its a brutal solution.

NSScrollView supports -reflectScrolledClipView. Calling this directly in my case had no effect except when delayed on the runloop:

[textScrollView performSelector:@selector(reflectScrolledClipView:) withObject:textScrollView.contentView afterDelay:0];

The scroller position is correct but there is a scroller redraw. So it looks as if part of the view geometry is calculated when drawing. A better solution is therefore:

NSDisableScreenUpdates();
[textScrollView display];
[textScrollView reflectScrolledClipView:textScrollView.contentView];
[textScrollView display];
NSEnableScreenUpdates();
胡大本事2024-12-30 15:02:00

基于上面 jstuxx 的答案,如果您不希望窗口明显调整大小,请尝试:

NSRect windowRect = [[[self view] window] frame];
windowRect.size.width += 1;
windowRect.size.height += 1;
[[[self view] window] setFrame:windowRect display:YES];
windowRect.size.width -= 1;
windowRect.size.height -= 1;
[[[self view] window] setFrame:windowRect display:YES];

我必须将此代码放在以编程方式将滚动视图添加到界面之后。

Building on the answer from jstuxx above, if you don't want the window to visibly resize, try:

NSRect windowRect = [[[self view] window] frame];
windowRect.size.width += 1;
windowRect.size.height += 1;
[[[self view] window] setFrame:windowRect display:YES];
windowRect.size.width -= 1;
windowRect.size.height -= 1;
[[[self view] window] setFrame:windowRect display:YES];

I had to put this code after where I was programmatically adding the scroll view to my interface.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文