NSScrollView:覆盖系统显示设置?

时间:2016-06-11 02:36:44

标签: objective-c macos cocoa nsscrollview nsscroller

我有 NSScrollView ,设置为:

$sql = "UPDATE users SET loggedin = '0' WHERE id = '$userid'";

我注意到,如果没有连接到OS X的触控板,默认情况下,MyNSScrollView.hasHorizontalScroller = YES; MyNSScrollView.hasVerticalScroller = YES; MyNSScrollView.autohidesScrollers = YES; MyNSScrollView.scrollerStyle = NSScrollerStyleOverlay; 将忽略代码中的设置并强制滚动条始终显示:

Settings

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

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

2之间的区别在于“遗留”样式将占用scrolllerview中的空格。如果您正在转发NO值进行计算,或者您的内容需要通过约束保持一定的宽高比,那将是一个问题。

有没有办法强制隐藏它们而不禁用它们?

2 个答案:

答案 0 :(得分:1)

您还不清楚在什么情况下会出现什么症状。例如,"显示滚动条的正常设置是什么:"在那个偏好窗格?你想要滚动条的行为是什么?始终可见?仅在滚动时显示?

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

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

答案 1 :(得分: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