【发布时间】:2021-08-03 08:13:12
【问题描述】:
我想使用名为LoadingView 的UIView 在UIViewController 上显示一个视图。但是,每当我尝试使用以下代码时,只会出现 UIView 而没有 CALayer。
理想情况下,当调用startLoading() 时,此代码会导致出现UIView。然后CALayer 将被添加到UIView 中,它将是一个围绕视图中心旋转的圆圈。我可以改变什么来让这个CALayer 在UIView 上以正确的方式显示?
class LoadingView: UIView {
let circleLayer = CAShapeLayer()
init() {
super.init(frame: .zero)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func startLoading() {
let size = 50
if let topView = UIApplication.topViewController()?.view {
topView.addSubview(self)
translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
self.centerYAnchor.constraint(equalTo: topView.centerYAnchor),
self.centerXAnchor.constraint(equalTo: topView.centerXAnchor),
self.widthAnchor.constraint(equalToConstant: CGFloat(size)),
self.heightAnchor.constraint(equalToConstant: CGFloat(size)),
])
self.layer.cornerRadius = frame.height/3
addShadow(shadowColor: UIColor.label.cgColor, shadowOffset: CGSize(width: 0, height: 0), shadowOpacity: 0.3, shadowRadius: 2)
backgroundColor = .secondarySystemBackground
animateCircle(duration: .infinity)
}
}
private func animateCircle(duration: TimeInterval) {
let circlePath = UIBezierPath(arcCenter: CGPoint(x: self.frame.midX, y: self.frame.midY), radius: (frame.size.width), startAngle: 0.0, endAngle: CGFloat(Double.pi*2), clockwise: true)
// Setup the CAShapeLayer with the path, colors, and line width
circleLayer.path = circlePath.cgPath
circleLayer.fillColor = UIColor.clear.cgColor
circleLayer.strokeColor = Constants.Colors.mainBlue?.cgColor
circleLayer.lineWidth = 1.0
// Don't draw the circle initially
circleLayer.strokeEnd = 0.0
// Add the circleLayer to the view's layer's sublayers
self.layer.addSublayer(circleLayer)
// We want to animate the strokeEnd property of the circleLayer
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 0
animation.toValue = 1
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
circleLayer.strokeEnd = 0
circleLayer.add(animation, forKey: "animateCircle")
let rotationAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
rotationAnimation.fromValue = 0.0
rotationAnimation.toValue = Double.pi*3
rotationAnimation.duration = duration
rotationAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn)
circleLayer.add(rotationAnimation, forKey: nil)
let fadeAnimation = CABasicAnimation(keyPath: "opacity")
fadeAnimation.fromValue = 1
fadeAnimation.toValue = 0
fadeAnimation.duration = duration
fadeAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn)
circleLayer.add(fadeAnimation, forKey: nil)
}
func stopLoading() {
self.removeFromSuperview()
}
}
【问题讨论】:
标签: ios swift xcode uiview calayer