【问题标题】:CALayer with NSScrollView, zooming panning and clicking带有 NSScrollView 的 CALayer,缩放平移和点击
【发布时间】:2015-02-11 01:52:31
【问题描述】:

我有一个 CALayer 托管视图,我希望能够对其进行缩放、滚动和点击。如果我将它嵌入到滚动视图中,滚动效果很好,但是缩放会导致内容到处飞散。如果我不将它嵌入到滚动视图中,我可以使用 CATransform3DMakeScale 很好地进行缩放,但是我在平移和选择对象时遇到了问题。

在我尝试用错误的选项解决之前,推荐的解决方法是什么。

(如果您有任何类似的来源,我将非常感激。)

【问题讨论】:

    标签: macos calayer nsview nsscrollview


    【解决方案1】:

    我在Apple sample codes 得到了启发

    另请查看Optimizing Drawing and Scrolling on OS X WWDC 2013 video

    嵌入在ScrollView 中的CALayer 飞了起来,因为ScrollView 不是核心动画层 (ScrollView.wantsLayer = true)。

    这里是 Swift 中的示例:

    @NSApplicationMain
    class AppDelegate: NSObject, NSApplicationDelegate {
        var win: NSWindow!
    
        func applicationDidFinishLaunching(aNotification: NSNotification) {
    
            win = NSWindow(contentRect: NSRect(x: 200, y: 200, width: 500, height: 500),
                styleMask: NSTitledWindowMask,
                backing: NSBackingStoreType.Buffered,
                defer: false)
    
            win.makeKeyAndOrderFront(win)
    
            let scrollView = NSScrollView()
            scrollView.allowsMagnification = true
            scrollView.hasHorizontalScroller = true
            scrollView.hasVerticalScroller = true
            scrollView.wantsLayer = true
    
            scrollView.contentView = CenteredClipView()
            scrollView.documentView = MyView()
            scrollView.backgroundColor = NSColor.controlColor()
    
            win.contentView = scrollView
        }
    }
    
    class MyView: NSView {
        var drawn = false
    
        override func updateLayer() {
            super.updateLayer()
    
            if !drawn {
                drawn = true
    
                frame = (superview! as NSView).frame
    
                var shape = CAShapeLayer()
                let p = CGPathCreateMutable()
                CGPathAddEllipseInRect(p, nil, frame)
                CGPathMoveToPoint(p, nil, bounds.maxX, 0)
                CGPathAddLineToPoint(p, nil, 0, bounds.maxY)
                shape.path = p
                shape.lineWidth = 5
                shape.fillColor = NSColor.whiteColor().CGColor
                shape.strokeColor = NSColor.selectedControlColor().CGColor
                shape.lineDashPattern = [5, 5]
    
                let ant = CABasicAnimation(keyPath: "lineDashPhase")
                ant.fromValue = 0
                ant.toValue = 1000000
                ant.duration = 10000
                ant.repeatCount = 10000
                shape.addAnimation(ant, forKey: "lineDashPhase")
    
                layer?.addSublayer(shape)
            }
        }
    }
    
    class CenteredClipView: NSClipView {
        override func constrainBoundsRect(proposedBounds: NSRect) -> NSRect {
            var rect = super.constrainBoundsRect(proposedBounds)
    
            if let containerView = documentView? as? NSView {
                if rect.size.width > containerView.frame.size.width {
                    rect.origin.x = (containerView.frame.width - rect.width ) / 2
                }
    
                if rect.size.height > containerView.frame.size.height {
                    rect.origin.y = (containerView.frame.height - rect.height ) / 2
                }
            }
    
            return rect
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      相关资源
      最近更新 更多