【问题标题】:Cocoa drawing on scrollable view dilema可可绘制的可滚动视图困境
【发布时间】:2016-01-19 11:49:39
【问题描述】:

我使用 Swift 开发我的第一个 OSX 应用程序,但我迷失在一些 Cocoa 概念中。

我在 NSScrollView 中放置了一个自定义 NSView。我在覆盖的 drawRect 函数中绘制复杂的图表。图表很大,但 NSScrollView 可以滚动整个视图。

我不满意的是,每次调用 drawRect 时我都会重绘整个图表,并且在滚动、调整大小等时会非常频繁地调用它。

绘制图表需要大量计算,需要绘制大量形状。每次调用 drawRect 时都这样做似乎是错误的。我知道我可以将绘图限制在可见/脏矩形,但它会更加复杂并且需要更多的计算。

有没有更好的方法来绘制这种可滚动的图表?最好将整个图表绘制一次,以后不用担心重新绘制它。

我想将来在我的图表中添加一些交互性(鼠标点击)。这可能是重要的信息。

谢谢

【问题讨论】:

    标签: swift macos cocoa nsview nsscrollview


    【解决方案1】:

    如果您的自定义视图在绘图期间不需要“实时”,这意味着滚动不会更改视图的内容,那么您可以通过多种方式执行此操作。

    我通过了解视图何时滚动来解决此类问题。您可能想要查看的一件事是为来自滚动视图的通知注册自定义视图。特别是NSScrollViewWillStartLiveScrollNotification。当视图滚动时,您可以将自定义视图缓存到 NSBitmapImageRep 并改为绘制它。我以前用一个非常复杂的视图做过这个,而且效果很好。

    另外一个可能更简单的东西是 NSScrollView 的 scrollsDynamically 属性。

    在 Swift 2 中,您可以使用以下帮助

    在你的awakeFromNib

    NSNotificationCenter.defaultCenter().addObserver(self, selector: "startScrolling", name: NSScrollViewWillStartLiveScrollNotification, object: self.scrollView)
    
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "endScrolling", name: NSScrollViewDidEndLiveScrollNotification, object: self.scrollView)
    

    然后

    func startScrolling() {
        //viewRep is an NSBitmapImageRep variable in your class
        //create a bitmap representation of your view
        self.lockFocus()
        self.viewRep = NSBitmapImageRep(focusedViewRect: self.bounds)
        self.unlockFocus()
    
        //set a flag which draw rect uses to know to draw the bitmaprep
        //viewRep is a Bool variable in your class
        self.scrollingFlag = true
        self.needsDisplay = true
    }
    
    func endScrolling() {
        self.scrollingFlag = false
        self.needsDisplay = true
    }
    

    你的绘图方法

    override func drawRect(dirtyRect: NSRect) {
        if self.scrolling {
             self.viewRep.drawInRect(....) // you can draw the viewRep here
        }
        else {
             //your normal drawing code here
        }
    }
    

    【讨论】:

    • @Marek drawRect 方法中的 if-else-statement 是否正常工作?
    • @Andy Federoff 对于我来说,它一直都有。我不明白为什么它不会。
    • @MAH 你能看看我的帖子吗?我遇到了drawRect的问题。 stackoverflow.com/questions/39855349/…
    • @AndyFedoroff 我不确定为什么它不起作用,但原因肯定不是 if-else-statement 不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多