动画边界更改时具有 CALayer 有线效果的自定义视图
Posted
技术标签:
【中文标题】动画边界更改时具有 CALayer 有线效果的自定义视图【英文标题】:Custom view with CALayer wired effect when animating bounds change 【发布时间】:2016-03-09 03:45:45 【问题描述】:我已经实现了一个自定义视图,其中添加了CALayer
作为UIView
的子层。当我使用以下内容为视图设置动画时:UIView.animateWithDuration(2.0) self.slider.bounds.size *= 2.0
,缩放动画有点错误。 CALayer
以缩放大小从错误位置开始并移动到最终位置,而不是随视图缩放。
CustomeView 代码:
import UIKit
class GridMaskView: UIView
private let cornerLayer: CAShapeLayer
private let borderLayer: CAShapeLayer
private let gridLayer: CAShapeLayer
private let gridSize: (horizontal: UInt, vertical: UInt) = (3, 3)
private let cornerThickness: CGFloat = 3.0
private let cornerLength: CGFloat = 20.0
private let borderThickness: CGFloat = 2.0
private let gridThickness: CGFloat = 1.0
private let lineColor: UIColor = UIColor(r: 120, g: 179, b: 193, a: 1)
var showGridLines: Bool = true
didSet
gridLayer.hidden = !showGridLines
required init?(coder aDecoder: NSCoder)
fatalError("init(coder:) has not been implemented")
override init(frame: CGRect)
cornerLayer = CAShapeLayer()
cornerLayer.fillColor = lineColor.CGColor
borderLayer = CAShapeLayer()
borderLayer.fillColor = UIColor.clearColor().CGColor
borderLayer.strokeColor = lineColor.CGColor
borderLayer.lineWidth = borderThickness
gridLayer = CAShapeLayer()
gridLayer.strokeColor = lineColor.CGColor
gridLayer.lineWidth = gridThickness
super.init(frame: frame)
layer.addSublayer(cornerLayer)
layer.addSublayer(borderLayer)
layer.addSublayer(gridLayer)
override func layoutSubviews()
super.layoutSubviews()
layoutLayers()
private func layoutLayers()
drawCorner()
drawBorder()
drawGrid()
private func drawCorner()
cornerLayer.frame = bounds.insetBy(dx: -cornerThickness, dy: -cornerThickness)
cornerLayer.path = cornerPath(forBounds: cornerLayer.bounds)
private func cornerPath(forBounds bounds: CGRect) -> CGPathRef
let horizontalSize = CGSize(width: cornerLength, height: cornerThickness)
let verticalSize = CGSize(width: cornerThickness, height: cornerLength)
let corners: [(CGRectEdge, CGRectEdge)] = [(.MinXEdge, .MinYEdge), (.MinXEdge, .MaxYEdge), (.MaxXEdge, .MinYEdge), (.MaxXEdge, .MaxYEdge)]
var cornerRects = [CGRect]()
for corner in corners
cornerRects.append(bounds.align(horizontalSize, corner: corner.0, corner.1))
cornerRects.append(bounds.align(verticalSize, corner: corner.0, corner.1))
let cornerPath = CGPathCreateMutable()
CGPathAddRects(cornerPath, nil, cornerRects, cornerRects.count)
return cornerPath
private func drawBorder()
borderLayer.frame = bounds
borderLayer.path = borderPath(forBounds: borderLayer.bounds)
private func borderPath(forBounds bounds: CGRect) -> CGPathRef
let borderPath = CGPathCreateMutable()
let borderCornerPoints = [bounds.topLeft, bounds.topRight, bounds.bottomRight, bounds.bottomLeft, bounds.topLeft]
CGPathAddLines(borderPath, nil, borderCornerPoints, borderCornerPoints.count)
return borderPath
private func drawGrid()
gridLayer.frame = bounds
gridLayer.path = gridPath(forBounds: gridLayer.bounds)
private func gridPath(forBounds bounds: CGRect) -> CGPathRef
let stepSize = bounds.size / (CGFloat(gridSize.horizontal), CGFloat(gridSize.vertical))
let gridPath = CGPathCreateMutable()
for i in (1...gridSize.vertical)
let x = CGFloat(i) * stepSize.width
CGPathMoveToPoint(gridPath, nil, x, 0)
CGPathAddLineToPoint(gridPath, nil, x, bounds.size.height)
for i in (1...gridSize.horizontal)
let y = CGFloat(i) * stepSize.height
CGPathMoveToPoint(gridPath, nil, 0, y)
CGPathAddLineToPoint(gridPath, nil, bounds.size.width, y)
return gridPath
override func intrinsicContentSize() -> CGSize
return CGSize(width: cornerLength * 2, height: cornerLength * 2)
有人知道怎么装吗?
【问题讨论】:
【参考方案1】:问题在于,当您查看动画时,您不会获得任何子图层的自动动画。您最好使用原始 UIView 的子视图,因为视图动画会根据其自动布局约束将其与原始视图一起制作动画。
【讨论】:
我正在实现一个自定义网格视图。似乎对每一行都使用 UIView 似乎有点奇怪。还有其他方法吗? 你已经隐瞒了你实际在做什么以及问题究竟是什么。您已经展示了五行完全没有信息的代码。你想要更好的帮助吗?显露,不隐瞒。更好的信息,更好的问题,更好的答案。现在你很幸运有人和你说话。 好吧,我坚持我所说的。您可以在单个视图的主层中进行所有绘制,使其成为另一个视图的子视图,并获得自动子视图动画的好处。否则,当您为视图设置动画时,您将不得不自己为所有这些图层设置动画。 所以我创建了一个自定义 CALayer 类并创建了一个 UIView 并将其 layerClass 覆盖到我的 CALayer 类中? 是的,或者甚至只是使用普通的 UIView 并直接在其中绘制。以上是关于动画边界更改时具有 CALayer 有线效果的自定义视图的主要内容,如果未能解决你的问题,请参考以下文章