简体   繁体   English

NSScrollView:覆盖系统显示设置?

[英]NSScrollView: Override system display settings?

I have a NSScrollView , which was set to: 我有一个NSScrollView ,设置为:

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

I noticed that when if there's no trackpad connecting to OS X, and by default, the NSScrollView will ignore my settings in the code and force the scrollers always shown: 我注意到,如果没有连接到OS X的触控板,并且默认情况下, NSScrollView将忽略代码中的设置并强制始终显示滚动条:

设置

I can only either change my system settings to " When scrolling " or set hasHorizontalScroller etc. to NO to hide it, and the later will disable mouse scrolling which is not the result I want. 我只能将我的系统设置更改为“ 滚动时 ”或将hasHorizontalScroller等设置为NO以隐藏它,后者将禁用鼠标滚动,这不是我想要的结果。

By default (Automatically based on mouse or trackpad) will always display the scroller if the user has no trackpad, even when the content size does not exceed the frame size. 默认情况下(如果用户没有触控板,将自动显示滚动条),即使内容大小不超过帧大小,也会始终显示滚动条。 But if you have a trackpad, it will be overlay style that no matter the scroller shows or not, it's above the content. 但是如果你有一个触控板,它将是叠加样式,无论卷轴显示与否,它都在内容之上。

The difference between the 2 is that "legacy" style will take up spaces in the scrollerview. 2之间的区别在于“遗留”样式将占用scrolllerview中的空格。 It'd be a problem if you were relaying on the visiableRect value for calculation, or your contents needs to remain certain aspect-ratio via constraints. 如果您使用visiableRect值进行计算,或者您的内容需要通过约束保持某些宽高比,那将是一个问题。

Is there a way to force hide them without disabling them? 有没有办法强制隐藏它们而不禁用它们?

You have not been clear about exactly what symptoms occur under what circumstances. 您还不清楚在什么情况下会出现什么症状。 For example, what is your normal setting for "Show scroll bars:" in that preference pane? 例如,在该首选项窗格中“显示滚动条:”的正常设置是什么? What do you want the behavior of the scrollers to be? 你想要滚动条的行为是什么? Always visible? 始终可见? Only show when scrolling? 滚动时才显示?

In any case, I think the issue is that you simply are misunderstanding what autohidesScrollers does. 无论如何,我认为问题在于你只是误解了autohidesScrollers所做的事情。 Setting that to true simply means that the scrollers are hidden when the document view does not extend past the bounds of the clip view (aka content view). 将其设置为true只是意味着当文档视图未超出剪辑视图(也称为内容视图)的边界时,会隐藏滚动条。 That is if there's no place to scroll to because everything is already showing. 那就是没有地方可以滚动,因为一切都已经显示出来了。

That property has nothing to do with the scrollers being visible always or only when scrolling or whatever. 该属性与滚动器始终可见或仅在滚动或其他任何情况下无关。 That's a system setting that you can't override programmatically. 这是一个无法以编程方式覆盖的系统设置。 All scrollers behave the same throughout all apps in the user session. 所有滚动条在用户会话中的所有应用程序中的行为相同。

You can force the whole app to use overlay scrollers by using some low-level Objective-C magic (method swizzling): 您可以通过使用一些低级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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM