NSScrollView 不滚动

NSScrollView not scrolling

我在 Mac 应用程序中有一个需要滚动的表单。我在 ViewController 中嵌入了一个 scrollView。我为 scrollView 分配了一个标识符,该标识符将它链接到它自己的 NSScrollView 文件。约束设置为视图控制器的顶部、右侧和左侧,它还将高度约束设置为 ViewController 的全高。

这是我的代码:

import Cocoa

class ScrollView: NSScrollView {

override func draw(_ dirtyRect: NSRect) {
    super.draw(dirtyRect)

    // Drawing code here.
    NSRect documentView.NSMakeSize(0, 0, 1058.width, 1232.height)
}

override func scrollWheel(with event: NSEvent) {
    switch event.phase {
    case NSEvent.Phase.began:
        Swift.print("Began")
//        case NSEvent.Phase.changed:
//            Swift.print("Changed")
    case NSEvent.Phase.ended:
        Swift.print("Ended")
    default:
        break
    }

    switch event.momentumPhase {
    case NSEvent.Phase.began:
        Swift.print("Momentum Began")
//        case NSEvent.Phase.changed:
//            Swift.print("Momentum Changed")
    case NSEvent.Phase.ended:
        Swift.print("Momentum Ended")
    default:
        break
    }
    super.scrollWheel(with: event)
}

我似乎根本无法让我的应用程序滚动。我想我没有正确设置框架。正确设置框架的最佳方法是什么?我对 NSScrollView 的编码是否正确?

我认为你正在让你的生活变得非常艰难,因为你正在做一些 Apple 不完全推荐的事情。首先,你不应该继承NSScrollView。相反,您应该首先阅读 Apple 的 Introduction to Scroll View Programming Guide for Cocoa 以了解您应该如何创建正确的视图层次结构以使 NSScrollView 正常工作。

第二个建议是让您查看此 nice article 关于您应该如何在游乐场中设置 NSScrollView 的内容,以便您可以使用您想要实现的代码。

第三,使用 Autolayout 和 NSScrollView 给很多人带来了很多痛苦。您需要正确设置 AutoLayout,以便一切都按预期工作。我建议您查看 Ken Thomases 的 ,它清楚地解释了您需要如何设置自动布局约束才能使 NSScrollView 正常工作。

我刚刚在 NSWindow 中使用 NSScrollView 克服了 "hump"。为了发生滚动,NSScrollview 中的视图需要大于内容 window。这很难用动态约束来设置。将内部视图静态设置为比 window "works" 更大的 width/height 但静态大小通常不是您想要的。

Here is my interface builder view hierarchy and constraints, not including the programmatically added boxes

在我的应用中,用户在 mainView 中添加 "boxes"(自定义可拖动视图),它位于 NSwindow.

的滚动视图中

这是我想要的功能:

  1. 如果我展开 NSWindow,我希望滚动视图中的 mainView 展开以填满整个 window。如果所有框都可见,则在这种情况下无需滚动。

  2. 如果我缩小 NSWindow,我希望滚动视图中的 mainView 缩小到足以包含我所有的 mainView 子视图("boxes"),但不会进一步缩小(我添加了一个 minBorder 20)。如果框的位置比 nswindow 的 width/height.

  3. 更远 right/up,这会导致滚动

我发现诀窍是根据每个可拖动框视图的最大角或 nswindow 的内容框架的 height/width 来计算我想要的 mainView 的大小,以哪个为准更大。

下面是我的代码,包括一些调试打印。

注意使用哪些子视图来计算最大尺寸。如果您包含一个动态附加到 window 的 right/top 的子视图,那么您的 window 将永远不会缩小。如果向其添加 +20 边框,则可能会无限循环。对我来说不是问题。

extension MapWindowController: NSWindowDelegate {
    func windowDidEndLiveResize(_ notification: Notification) {
        if let frame = window?.frame, let content = window?.contentRect(forFrameRect: frame) {
            print("window did resize \(frame)")
            var maxX: CGFloat = content.width
            var maxY: CGFloat = content.height
            for view in mainView?.subviews ?? [] {
                let frameMaxX = view.frame.maxX + minBorder
                let frameMaxY = view.frame.maxY + minBorder
                if frameMaxX > maxX {
                    maxX = frameMaxX
                }
                if frameMaxY > maxY {
                    maxY = frameMaxY
                }
            }
            print("view maxX \(maxX) maxY \(maxY)")
            print("window width \(content.width) height \(content.height)")
            mainView?.setFrameSize(NSSize(width: maxX, height: maxY))
        }
    }
}