【问题标题】:autohide only horizontal scroller in NSScrollView在 NSScrollView 中仅自动隐藏水平滚动条
【发布时间】:2011-02-16 08:36:25
【问题描述】:

我有一个从 IB 创建的 NSTableView,我只想自动隐藏水平滚动条。我想这样做的主要原因是因为似乎 NSTableView corverView 只有在有垂直滚动条时才会显示。

我找不到任何方法可以对基类执行此操作。所以我尝试继承 NSScrollView 并观察水平滚动条上的隐藏键(下面的代码)。这行得通;但是,每次用户调整窗口大小时,视图都会尝试重置当前可见选项。这使我的实现有些昂贵;这似乎不优雅。关于如何做到这一点有更好的想法吗?

提前致谢!

当前实现:

@interface PVScrollView : NSScrollView {
  BOOL autohidesHorizontalScroller;
}

@property(assign) BOOL autohidesHorizontalScroller;

- (void) viewResized:(NSNotification*)notification;

@end

@implementation PVScrollView

@synthesize autohidesHorizontalScroller;

- (void) setAutohidesHorizontalScroller:(BOOL)val
{
  autohidesHorizontalScroller = val;
  [self setAutohidesScrollers:NO];
  [[self horizontalScroller] addObserver:self 
                              forKeyPath:@"hidden"
                                 options:0 
                                 context:nil];

}

- (void) observeValueForKeyPath:(NSString *)keyPath 
                       ofObject:(id)object 
                         change:(NSDictionary *)change 
                        context:(void *)context
{
  if (!([self documentVisibleRect].size.width < [[self documentView] frame].size.width) )
  {
    // remove observer
    [[self horizontalScroller] removeObserver:self
                                   forKeyPath:@"hidden"];
    [[self horizontalScroller] setHidden:YES];
    //[[self horizontalScroller] setNeedsDisplay:YES];
    // add it back
    [[self horizontalScroller] addObserver:self 
                                forKeyPath:@"hidden"
                                   options:0 
                                   context:nil];
  }
}

@end

【问题讨论】:

  • 我想说不要担心它,直到你发现它实际上会导致性能问题。过早的优化是不好的。
  • 我倾向于同意 Douwe 的观点,但是我要补充一点,通过使用 Instruments 来分析代码,您仍然可以相当容易地发现潜在的性能问题。过早的优化并不总是如此。有时,当你知道它可能表现不佳时,在对其进行压力测试时对其进行分析是唯一合乎逻辑的做法。在您知道它可能开始时忽略它直到它引起问题比“过早”优化更不合乎逻辑。 :-)
  • 我已经通过仪器运行了它。如果用户正在积极调整大小,它可能会占用高达 50% 的 cpu,而基本实现则相当稳定地占用 25%。我同意过早的优化,但困扰我的是解决方案的优雅。我不喜欢每次都重置和重新渲染;对于像自动隐藏只有 1 个滚动条这样简单的事情!

标签: objective-c cocoa macos nsscrollview


【解决方案1】:

在你的 NSScrollView 子类中试一试:

- (void)setFrameSize:(NSSize)newSize;
{
    NSSize minFrameSize = [NSScrollView frameSizeForContentSize:[self contentSize] hasHorizontalScroller:NO hasVerticalScroller:YES borderType:[self borderType]];
    BOOL wantScroller = minFrameSize.width > newSize.width;
    [self setHasHorizontalScroller:wantScroller];        
    [super setFrameSize: newSize];
}

您需要选中“显示垂直滚动条”并取消选中“自动隐藏滚动条”才能正常工作;我没有费心让它适应 IB 的变化。此外,您需要在第一次显示窗口时(在 NSScrollView 构造函数中)执行相同的操作。

我比较了有和没有这个变化的 CPU 使用率;在我的测试应用程序中,它似乎最多变化 1%(19%→20%)。

【讨论】:

    猜你喜欢
    • 2013-04-23
    • 1970-01-01
    • 2017-06-26
    • 1970-01-01
    • 2012-10-28
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 2011-06-18
    相关资源
    最近更新 更多