6

我有一个NSScrollView,它被设置为:

MyNSScrollView.hasHorizontalScroller = YES;
MyNSScrollView.hasVerticalScroller = YES;
MyNSScrollView.autohidesScrollers = YES;
MyNSScrollView.scrollerStyle = NSScrollerStyleOverlay;

我注意到,如果没有触控板连接到 OS X,并且默认情况下,NSScrollView它将忽略我在代码中的设置并强制滚动条始终显示:

设置

我只能将我的系统设置更改为“滚动时”或设置hasHorizontalScrollerNO以隐藏它,后者将禁用鼠标滚动,这不是我想要的结果。

默认情况下(自动基于鼠标或触控板)如果用户没有触控板,将始终显示滚动条,即使内容大小不超过帧大小。但是如果你有一个触控板,它将是覆盖样式,无论滚动条是否显示,它都在内容之上。

2 之间的区别在于“传统”样式将占用滚动视图中的空间。如果您要传递visiableRect计算值,或者您的内容需要通过约束保持一定的纵横比,那将是一个问题。

有没有办法在不禁用它们的情况下强制隐藏它们?

4

2 回答 2

1

您还不清楚在什么情况下会出现什么症状。例如,该首选项窗格中“显示滚动条:”的正常设置是什么?您希望滚动条的行为是什么?总是可见的?只在滚动时显示?

无论如何,我认为问题在于您只是误解了做什么autohidesScrollers。将其设置为 true 仅仅意味着当文档视图没有超出剪辑视图(又名内容视图)的边界时,滚动条被隐藏。也就是说,如果没有地方可以滚动,因为一切都已经显示出来了。

该属性与滚动条始终可见或仅在滚动或其他任何情况下可见无关。这是您无法以编程方式覆盖的系统设置。在用户会话中的所有应用程序中,所有滚动条的行为都相同。

于 2016-06-11T04:39:36.280 回答
0

您可以通过使用一些低级的 Objective-C 魔法(方法调配)来强制整个应用程序使用覆盖滚动条:

#import <Cocoa/Cocoa.h>
#import <objc/runtime.h>

static IMP old_preferredScrollerStyle = NULL;
static NSScrollerStyle new_preferredScrollerStyle(id self, SEL _cmd) {
    // Always prefer overlay style.
    return NSScrollerStyleOverlay;
}

static IMP old_setScrollerStyle = NULL;
static void new_setScrollerStyle(id self, SEL _cmd, NSScrollerStyle style) {
    // Call old implementation but always with overlay style.
    void(*oldImp)(id self, SEL _cmd, NSScrollerStyle style)
        = (void(*)(id, SEL, NSScrollerStyle))old_setScrollerStyle;
    oldImp(self, _cmd, NSScrollerStyleOverlay);
}

/// Force the overlay style scrollers for this app.
@interface NSScrollView (ForceOverlay)
@end

@implementation NSScrollView (ForceOverlay)

+ (void)load
{
    [super load];

    // Replace the preferred style. This sets the style for app startup and new NSScroller
    // and NSScrollView instances.
    Method originalMethod = class_getClassMethod(
        [NSScroller class],
        @selector(preferredScrollerStyle)
    );
    old_preferredScrollerStyle = method_setImplementation(
        originalMethod,
        (IMP)new_preferredScrollerStyle
    );

    // Replace the NSScrollView setter. This prevents the change to the legacy style, for example
    // when the user switches the system setting.
    originalMethod = class_getInstanceMethod(
        [NSScrollView class],
        @selector(setScrollerStyle:)
    );
    old_setScrollerStyle = method_setImplementation(
        originalMethod,
        (IMP)new_setScrollerStyle
    );
}

@end
于 2017-04-05T09:49:06.020 回答