NSScrollView不滚动

时间:2018-10-29 18:53:32

标签: swift macos cocoa nsscrollview

我在MacApp中有一个需要滚动的表单。我有一个ViewView中嵌入的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吗?

谢谢

科尔

2 个答案:

答案 0 :(得分:2)

我认为您的生活非常艰辛,因为您所做的事情不是Apple完全推荐的。首先,您不应该继承NSScrollView的子类。相反,您应该首先阅读Apple的Introduction to Scroll View Programming Guide for Cocoa,以了解如何为NSScrollView创建正确的视图层次结构。

第二项建议是让您查看此nice article,了解如何在操场上设置NSScrollView,以便可以使用要实现的代码。

第三,使用自动排版和NSScrollView给很多人带来了很多痛苦。您需要正确设置AutoLayout,以便所有功能都能按预期工作。我建议您检查一下Ken Thomases的answer,它清楚地说明了如何设置自动布局约束以使NSScrollView正常工作。

答案 1 :(得分:0)

我刚刚在NSWindow中使用NSScrollView克服了“驼峰”。为了进行滚动,NSScrollview内部的视图必须大于内容窗口。动态约束很难设置。将内部视图静态设置为比“工作”窗口更大的宽度/高度,但是静态尺寸通常不是您想要的。

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

在我的应用中,用户正在mainView中添加“框”(自定义可拖动视图),该视图位于NSwindow的滚动视图中。

这是我想要的功能:

1)如果我扩展了NSWindow,我希望在scrollview中的mainView能够扩展以填充整个窗口。如果所有框都可见,则在这种情况下无需滚动。

2)如果我收缩NSWindow,我希望滚动视图内的mainView缩小到足以包含我所有mainView子视图(“框”)的程度,但不能再缩小(我添加了20的minBorder)。如果框的位置比nswindow的宽度/高度更靠右/上方,则会导致滚动。

我发现诀窍是根据每个可拖动BoxView的最大角或nswindow内容框架的高度/宽度(以较大者为准)计算所需的mainView的大小。

下面是我的代码,包括一些调试信息。

请注意用于计算最大大小的子视图。如果您包含动态附加到窗口右侧/顶部的子视图,则您的窗口将永远不会缩小。如果您添加+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))
        }
    }
}