【问题标题】:NSTextView inside NSTableView Blocks ScrollingNSTableView 中的 NSTextView 阻止滚动
【发布时间】:2017-08-09 05:19:09
【问题描述】:

我有一个NSTableView,在每个表格行中都有一个NSTextView。我在情节提要中禁用了NSTextView 的滚动功能。我可以滚动我的NSTableView 就好了,但是当我的鼠标光标在NSTextView 的顶部时,滚动停止。我认为这是因为NSTextView 正在拦截滚动行为。

箭头指向NSTextView

请记住,NSTextViewNSTableViewCell 的子类。

class AnnouncementsVC: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
  @IBOutlet weak var tableView: NSTableView!

  override func viewDidLoad() {
    //...
  }
  func numberOfRows(in tableView: NSTableView) -> Int {
    //...
  }
  func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
    //...
  }
}

class AnnouncementTableCell: NSTableCellView{
  @IBOutlet weak var message: NSTextView!
}

如何使NSTextView 将其滚动事件传递给其父NSTableView?我的猜测是我需要scrollWheel(with event: NSEvent),但我不确定它的去向,因为我在这里有两个不同的课程。

【问题讨论】:

  • 您需要NSTextView 还是可以使用多行NSTextField
  • 我选择了NSTextView,以便调整行高。我想我可以使用 NSTextField 并改用属性字符串。

标签: nstableview nstextview nsscrollview


【解决方案1】:

这是一个运行良好的 Swift (4.2) 版本:

class MyScrollClass: NSScrollView{
  override func scrollWheel(with event: NSEvent) {
    self.nextResponder?.scrollWheel(with: event)
  }
}

只需将该子类添加到您的NSScrollView,它应该可以工作。

【讨论】:

  • 在我的情况下,它是一个 WKWebView,它正在“窃取”滚动,所以我将 WKWebView 子类化并像这样覆盖 scrollWheel()。谢谢。
【解决方案2】:

实现此目的的一种方法是继承 NSScrollView 并实现 scrollWheel: 以有条件地 (1) 根据需要使用子类实例中的滚动事件,或 (2) 将它们转发到封闭的滚动视图,基于在您的实例的当前滚动位置上。

这是我过去使用的一个相当基本的实现(Obj-C):

- (void)scrollWheel:(NSEvent *)e {


    if(self.enclosingScrollView) {

        NSSize
        contSize = self.contentSize,
        docSize = [self.documentView bounds].size,
        scrollSize = NSMakeSize(MAX(docSize.width  - contSize.width, 0.0f),
                                MAX(docSize.height - contSize.height,0.0f) );

        NSPoint
        scrollPos = self.documentVisibleRect.origin,
        normPos = NSMakePoint(scrollSize.width  ? scrollPos.x/scrollSize.width  : 0.0,
                              scrollSize.height ? scrollPos.y/scrollSize.height : 0.0 );

        if( ((NSView*)self.documentView).isFlipped ) normPos.y = 1.0 - normPos.y;

        if(   ( e.scrollingDeltaX>0.0f && normPos.x>0.0f) 
           || ( e.scrollingDeltaX<0.0f && normPos.x<1.0f)
           || ( e.scrollingDeltaY<0.0f && normPos.y>0.0f)
           || ( e.scrollingDeltaY>0.0f && normPos.y<1.0f) ) {

            [super scrollWheel:e];

        }
        else

            [self.nextResponder scrollWheel:e];

    }
    else 
        // Don't bother when not nested inside another NSScrollView
        [super scrollWheel:e];
}

它仍然有很多不足之处,例如独立处理 deltaX 和 deltaY 组件,但对于您的情况来说可能已经足够了。

【讨论】:

  • 我找到了一个相当于我将作为附加答案发布的 Swift,但我基本上在做你描述的同样的事情。谢谢!
猜你喜欢
  • 2020-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-20
  • 1970-01-01
  • 2016-02-19
  • 2012-09-30
相关资源
最近更新 更多