【问题标题】:Disable scrolling in NSTableView在 NSTableView 中禁用滚动
【发布时间】:2012-09-27 16:48:15
【问题描述】:

有没有一种简单的方法可以禁用 NSTableView 的滚动。

似乎没有任何属性 [myTableView enclosingScrollView][[myTableView enclosingScrollView] contentView] 禁用它。

【问题讨论】:

    标签: objective-c macos scroll nstableview nsscrollview


    【解决方案1】:

    这对我有用:子类 NSScrollView,设置和覆盖通过:

    - (id)initWithFrame:(NSRect)frameRect; // in case you generate the scroll view manually
    - (void)awakeFromNib; // in case you generate the scroll view via IB
    - (void)hideScrollers; // programmatically hide the scrollers, so it works all the time
    - (void)scrollWheel:(NSEvent *)theEvent; // disable scrolling
    
    @interface MyScrollView : NSScrollView
    @end
    
    #import "MyScrollView.h"
    
    @implementation MyScrollView
    
    - (id)initWithFrame:(NSRect)frameRect
    {
        self = [super initWithFrame:frameRect];
        if (self) {
            [self hideScrollers];
        }
    
        return self;
    }
    
    - (void)awakeFromNib
    {
        [self hideScrollers];
    }
    
    - (void)hideScrollers
    {
        // Hide the scrollers. You may want to do this if you're syncing the scrolling
        // this NSScrollView with another one.
        [self setHasHorizontalScroller:NO];
        [self setHasVerticalScroller:NO];
    }
    
    - (void)scrollWheel:(NSEvent *)theEvent
    {
        // Do nothing: disable scrolling altogether
    }
    
    @end
    

    我希望这会有所帮助。

    【讨论】:

    • 更准确地说:一个 NSTableView 不是一个 NSScrollView,它包含在一个中。所以你必须将封闭的 NSScrollView 更改为这个自定义类。
    • 我投了反对票,因为如果这是一个工作滚动视图的子视图,这会导致奇怪和用户敌对的行为
    【解决方案2】:

    这是我认为最好的解决方案:

    斯威夫特 5

    import Cocoa
    
    @IBDesignable
    @objc(BCLDisablableScrollView)
    public class DisablableScrollView: NSScrollView {
        @IBInspectable
        @objc(enabled)
        public var isEnabled: Bool = true
    
        public override func scrollWheel(with event: NSEvent) {
            if isEnabled {
                super.scrollWheel(with: event)
            }
            else {
                nextResponder?.scrollWheel(with: event)
            }
        }
    }
    


    只需将任何NSScrollView 替换为DisablableScrollView(或BCLDisablableScrollView,如果您仍在使用ObjC)就完成了。只需在代码或 IB 中设置isEnabled,它就会按预期工作。

    它的主要优点是嵌套滚动视图;在不将事件发送给下一个响应者的情况下禁用子级也会在光标位于禁用的子级上时有效地禁用父级。

    这里列出了这种方法的所有优点:

    • ✅ 禁用滚动
      • ✅ 以编程方式进行,默认行为正常
    • ✅ 不中断父视图的滚动
    • ✅ Interface Builder 集成
    • ✅ 替换NSScrollView
    • ✅ Swift 和 Objective-C 兼容

    【讨论】:

    • 鉴于这个问题被标记为objective-c,很奇怪你的意见是一个快速的答案(根据我的小知识,这似乎只不过是现有目标c的一个端口答案)是“最好的”。介意你详细说明吗?
    • @mah 好吧,首先这个问题是在 Swift 上市之前提出的,所以我怀疑 OP 真的特别需要 ObjC 答案? 其次,如果你阅读了我的答案中的非代码文本,你会看到主要优势。除了这一优势,这还包括 IB 集成。此外,in 将其他几个答案的想法合并为一个。
    • 好吧,除非操作员将他/她的代码库从 ObjC 转移到 swift,否则我不希望他们的需求发生变化 ;) 但是添加 IB 很酷(而且我没有掌握在您发表评论之前-就像我提到的那样,我的快速知识很少。)。谢谢!
    • 这就是 Swift 的魅力所在。只需将其放入 Xcode 并告诉它创建一个桥接头......你就完成了。我开始编写一个 Objective-C 版本(如果你想看的话,它在源代码中被注释掉了),但是当我意识到我必须重写构造函数只是为了为isEnabled 提供默认的true 值时就停止了。无论哪种方式,这也可以在 ObjC 中使用而无需修改! :D
    • BCLDisablableScrollView 是什么?
    【解决方案3】:

    感谢@titusmagnus 的回答,但我做了一个修改,以免在“禁用”滚动视图嵌套在另一个滚动视图中时中断滚动:当光标在边界内时,您无法滚动外部滚动视图内部滚动视图。如果你这样做......

    - (void)scrollWheel:(NSEvent *)theEvent
    {
        [self.nextResponder scrollWheel:theEvent];
        // Do nothing: disable scrolling altogether
    }
    

    ...那么“禁用”的滚动视图会将滚动事件向上传递到外部滚动视图,并且它的滚动不会卡在其子视图中。

    【讨论】:

    • 这个答案在我看来是解决 NSTextView 默认放置在滚动容器中的最实用方法。谢谢。
    【解决方案4】:

    为我工作:

    - (void)scrollWheel:(NSEvent *)theEvent
    {
        [super scrollWheel:theEvent];
    
        if ([theEvent deltaY] != 0)
        {
            [[self nextResponder] scrollWheel:theEvent];
        }
    }
    

    【讨论】:

      【解决方案5】:

      没有简单直接的方法(也就是说,没有像 UITableView 的 scrollEnabled 这样可以设置的属性),但我发现 this answer 在过去很有帮助。

      您可以尝试的另一件事(不确定)是子类化NSTableView 并覆盖-scrollWheel-swipeWithEvent,所以它们什么都不做。希望这会有所帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-09-13
        • 2015-12-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多