我已经使用CAShapeLayer
创建了一个自定义的循环进度栏。我可以使用UIView
轻松将其居中放置在任何view.center
中,但是我需要将其居中放置在UITableView
单元中,这就是我得到的:
如果您查看该图像,上方的圆圈会正确显示CAShapeLayer
内的同一UIView
。
我已经尝试过view.center, [x: view.frame.width /2, y :view.frame.height / 2 ]
我还尝试将UIView
内的Cell
居中,并将CAShapeLayer
添加到居中的视图中。...不起作用。
let center = CGPoint(x: self.frame.width/2, y: self.frame.height/2)
let circularPath = UIBezierPath(arcCenter: .zero, radius: 80, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
pulsatingLayer.position = center
完整代码:
import UIKit
class CurrentGACell: UITableViewCell {
let shapeLayer = CAShapeLayer()
var pulsatingLayer: CAShapeLayer!
let percentageLabel: UILabel = {
var label = UILabel()
label.text = "Start"
label.textAlignment = .center
label.font = UIFont(name: "AvenirNext-DemiBold", size: 30)
label.backgroundColor = UIColor.clear
return label
}()
@IBOutlet weak var mainView: UIView!
override func awakeFromNib() {
super.awakeFromNib()
setupNotificationObserver()
let center = self.contentView.center //CGPoint(x: contentView.frame.width/2, y: contentView.frame.height/2) //mainView.center
let circularPath = UIBezierPath(arcCenter: .zero, radius: 80, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
//pulsating
pulsatingLayer = CAShapeLayer()
pulsatingLayer.path = circularPath.cgPath
pulsatingLayer.fillColor = UIColor.AppColors.Blue.withAlphaComponent(0.2).cgColor
pulsatingLayer.strokeColor = UIColor.clear.cgColor
pulsatingLayer.lineWidth = 10
pulsatingLayer.lineCap = .round
pulsatingLayer.position = center
self.contentView.layer.addSublayer(pulsatingLayer)
animatePulsatingLayer()
//trackLayer
let trackLayer = CAShapeLayer()
trackLayer.path = circularPath.cgPath
trackLayer.fillColor = UIColor.white.cgColor
trackLayer.strokeColor = UIColor.AppColors.Blue.withAlphaComponent(0.2).cgColor
trackLayer.lineWidth = 10
trackLayer.lineCap = .round
trackLayer.position = center
self.contentView.layer.addSublayer(trackLayer)
//shapeLayer
shapeLayer.path = circularPath.cgPath
shapeLayer.fillColor = UIColor.white.cgColor
shapeLayer.strokeColor = UIColor.AppColors.Blue.cgColor
shapeLayer.lineWidth = 10
shapeLayer.strokeEnd = 0
shapeLayer.lineCap = .round
shapeLayer.position = center
shapeLayer.transform = CATransform3DMakeRotation(-CGFloat.pi/2, 0, 0, 1)
self.contentView.layer.addSublayer(shapeLayer)
self.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
self.contentView.addSubview(percentageLabel)
percentageLabel.frame = CGRect(x: 0, y: 0, width: 500, height: 100)
percentageLabel.center = center
}
@objc private func handleTap() {
//beginDownloading()
animateCircle()
}
fileprivate func animateCircle() {
print("animating....")
let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")
basicAnimation.toValue = 0.65
basicAnimation.duration = 1
basicAnimation.fillMode = CAMediaTimingFillMode.forwards
basicAnimation.isRemovedOnCompletion = false
percentageLabel.text = "29w + 3d"
shapeLayer.add(basicAnimation, forKey: "urSoBasic")
}
private func animatePulsatingLayer() {
let animation = CABasicAnimation(keyPath: "transform.scale")
animation.toValue = 1.2
animation.duration = 1
animation.autoreverses = true
animation.repeatCount = Float.infinity
animation.timingFunction = CAMediaTimingFunction(name: .easeOut)
pulsatingLayer.add(animation, forKey: "pulsating")
}
private func setupNotificationObserver() {
NotificationCenter.default.addObserver(self, selector: #selector(handleEnterForegroung), name: UIApplication.willEnterForegroundNotification, object: nil)
}
@objc func handleEnterForegroung() {
animatePulsatingLayer()
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
答案 0 :(得分:0)
您需要将所有代码添加到layoutSubviews
方法中。
let shapeLayer = CAShapeLayer()
override func layoutSubviews() {
let circularPath = UIBezierPath(arcCenter: .zero, radius: 25, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
shapeLayer.path = circularPath.cgPath
shapeLayer.strokeColor = UIColor.blue.cgColor
shapeLayer.fillColor = UIColor.gray.cgColor
shapeLayer.lineWidth = 1.0
shapeLayer.position = self.contentView.center
if !self.contentView.layer.sublayers!.contains(shapeLayer){
self.layer.addSublayer(shapeLayer)
}
}
您可以使用UIScreen
的静态值
override func awakeFromNib() {
super.awakeFromNib()
let point = CGPoint.init(x: UIScreen.main.bounds.width/2, y: self.contentView.frame.height/2)
let circularPath = UIBezierPath(arcCenter: .zero, radius: 25, startAngle: 0, endAngle: CGFloat.pi * 2, clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circularPath.cgPath
shapeLayer.strokeColor = UIColor.blue.cgColor
shapeLayer.fillColor = UIColor.gray.cgColor
shapeLayer.lineWidth = 1.0
shapeLayer.position = point
self.layer.addSublayer(shapeLayer)
}
注意:
由于在帧渲染之前添加了一个图层,所以得到了不可预测的结果。
答案 1 :(得分:-1)
将依赖于.contentView
框架的代码移动到layoutSubviews()
。只有这样,才能保证您的CurrentGACell
具有正确的框架。
类似的东西:
let shapeLayer = CAShapeLayer()
let trackLayer = CAShapeLayer()
var pulsatingLayer: CAShapeLayer!
func layoutSubviews() {
super.layoutSubviews()
let center = contentView.center
pulsatingLayer.position = center
trackLayer.position = center
shapeLayer.position = center
percentageLabel.center = center
}