gpt4 book ai didi

swift - 如何使 CALayer 及其所有子层按比例缩放?

转载 作者:搜寻专家 更新时间:2023-10-31 23:05:16 25 4
gpt4 key购买 nike

我正在尝试制作一个显示文档页面的 NSScrollView。我添加了一个支持 CALayer 的 NSView 作为 NSScrollView 的 documentView,然后我向 documentView 添加了一个 CALayer 子层。当我缩放 NSScollview 时,documentView 会正确放大和缩小。但是,documentView 的子层不会与其包含的 documentView 成比例地缩放。如果我没有在 documentView 层的子层上设置 autoresizingMask,当 documentView 缩放时,子层就会飞离屏幕。如果我使用 LayerWidthSizable/LayerHeightSizable 选项,子层会变得比它们引用 documentView 超层时应有的更大或更小。这是我到目前为止的代码:

这是 NSScrollview:

class LayerScrollView: NSScrollView {

var containerLayer: ContainerLayer!

override func awakeFromNib() {
documentView = ContainerLayer(frame: frame)
}
}

这是 ContainerLayer(documentView CALayer):

class ContainerLayer: NSView {

let documentLayer: DocumentLayer = DocumentLayer()

override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
autoresizesSubviews = true
wantsLayer = true
layer = CATiledLayer()
layer?.delegate = self
layer?.backgroundColor = NSColor.blueColor().CGColor
layer?.masksToBounds = true
documentLayer.frame = CGRect(x: frame.width / 4.0, y: frame.height / 4.0, width: frame.width / 2.0, height: frame.height / 2.0)
documentLayer.delegate = documentLayer
layer?.addSublayer(documentLayer)
documentLayer.autoresizingMask = CAAutoresizingMask.LayerWidthSizable | CAAutoresizingMask.LayerHeightSizable
documentLayer.setNeedsDisplay()
}

required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func drawLayer(layer: CALayer!, inContext ctx: CGContext!) {
CGContextSetFillColorWithColor(ctx, NSColor.redColor().CGColor)
CGContextFillRect(ctx, layer.bounds)
}
}

最后,这是 DocumentLayer(DocumentLayer 中包含的子层):

class DocumentLayer: CALayer {

override func drawLayer(layer: CALayer!, inContext ctx: CGContext!) {
CGContextSetFillColorWithColor(ctx, NSColor.redColor().CGColor)
CGContextFillRect(ctx, layer.bounds)
}
}

这是一张图片来说明问题和我想要的结果:

蓝色矩形是ContainerLayer,红色矩形是DocumentLayer。

我浏览了许多教程和文档,但一无所获。看起来这应该非常容易做到。我在这里缺少什么?

最佳答案

更新:已解决

这是解决方案,经过更多小时的文档和其他资料挖掘后找到(同时感谢@mahaltertin 建议我使用 borderWidth 来帮助调试):

图层 ScrollView :

class LayerScrollView: NSScrollView {

var containerLayer: ContainerLayer!

override func awakeFromNib() {
containerLayer = ContainerLayer(frame: frame)
documentView = containerLayer
}
}

容器层:

class ContainerLayer: NSView {

let documentLayer: DocumentLayer = DocumentLayer()

override init(frame frameRect: NSRect) {
super.init(frame: frameRect)
wantsLayer = true
layer = CALayer()
layer?.layoutManager = CAConstraintLayoutManager.layoutManager()
layer?.delegate = self
layer?.backgroundColor = NSColor.blueColor().CGColor

documentLayer.delegate = documentLayer
documentLayer.name = "documentLayer"
documentLayer.borderWidth = 1.0
documentLayer.backgroundColor = NSColor.redColor().CGColor

documentLayer.addConstraint(CAConstraint(attribute: CAConstraintAttribute.Width, relativeTo: "superlayer", attribute: CAConstraintAttribute.Width, scale: 0.5, offset: 0.0))
documentLayer.addConstraint(CAConstraint(attribute: CAConstraintAttribute.Height, relativeTo: "superlayer", attribute: CAConstraintAttribute.Height, scale: 0.5, offset: 0.0))
documentLayer.addConstraint(CAConstraint(attribute: CAConstraintAttribute.MidX, relativeTo: "superlayer", attribute: CAConstraintAttribute.MidX, scale: 1.0, offset: 0.0))
documentLayer.addConstraint(CAConstraint(attribute: CAConstraintAttribute.MidY, relativeTo: "superlayer", attribute: CAConstraintAttribute.MidY, scale: 1.0, offset: 0.0))

layer?.addSublayer(documentLayer)

layer?.setNeedsDisplay()
documentLayer.setNeedsDisplay()
}

required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

还有文档层:

class DocumentLayer: CALayer {

override func actionForKey(event: String!) -> CAAction! {
return nil
}
}

解决方案是使用约束。覆盖 DocumentLayer 中的 actionForKey 方法是为了防止 DocumentLayer 在缩放时设置动画。 ContainerLayer 中定义的约束指定 DocumentLayer 的宽度/高度应为 ContainerLayer 的一半,并且两层的中间位置应相同。缩放现在可以保持比例正确。

关于swift - 如何使 CALayer 及其所有子层按比例缩放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25729405/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com