我正在嘗試在我的 UItableviewCell 類中創建一個帶有計時器功能的圓形進度條。我創建了一個自定義類計時器,并且我正在使用來自 - 
下面是我的代碼,我無法同時看到正面 CAShapeLayer 和背景 CAShapeLayer。當我初始化常量“progressBar”時,我懷疑存在邏輯錯誤。
請告知是否可以使用自定義 ProgressBar 類,而不是重寫整個代碼。
import Foundation
import UIKit
import IQKeyboardManagerSwift
class ActiveExerciseTableViewCell: UITableViewCell, UITextFieldDelegate {
let progressBar: ProgressBar = {
let progressBar = ProgressBar()
return progressBar
}()
lazy var activeExerciseTimerUIView: UIView = { [weak self] in
let activeExerciseTimerUIView = UIView()
activeExerciseTimerUIView.backgroundColor = .black
activeExerciseTimerUIView.isUserInteractionEnabled = true
activeExerciseTimerUIView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(tapTimerView)))
return activeExerciseTimerUIView
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.addSubview(activeExerciseTimerUIView)
}
override func layoutSubviews() {
super.layoutSubviews()
setUpActiveExerciseUIViewLayout()
}
func setUpActiveExerciseUIViewLayout(){
activeExerciseTimerUIView.translatesAutoresizingMaskIntoConstraints = false
activeExerciseTimerUIView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
activeExerciseTimerUIView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: (contentView.frame.height-tableviewContentViewTabBarHeight)*0.25).isActive = true
activeExerciseTimerUIView.widthAnchor.constraint(equalToConstant: 225).isActive = true
activeExerciseTimerUIView.heightAnchor.constraint(equalToConstant: 225).isActive = true
activeExerciseTimerUIView.layer.cornerRadius = activeExerciseTimerUIView.frame.width/2
progressBar.frame = CGRect(
x: 0,
y: 0,
width: activeExerciseTimerUIView.frame.width,
height: activeExerciseTimerUIView.frame.height)
self.activeExerciseTimerUIView.addSubview(progressBar)
}
下面是來自源檔案的自定義 ProgressBar 類。
import UIKit
class ProgressBar: UIView, CAAnimationDelegate {
fileprivate var animation = CABasicAnimation()
fileprivate var animationDidStart = false
fileprivate var timerDuration = 0
lazy var fgProgressLayer: CAShapeLayer = {
let fgProgressLayer = CAShapeLayer()
return fgProgressLayer
}()
lazy var bgProgressLayer: CAShapeLayer = {
let bgProgressLayer = CAShapeLayer()
return bgProgressLayer
}()
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
loadBgProgressBar()
loadFgProgressBar()
}
override init(frame: CGRect) {
super.init(frame: frame)
loadBgProgressBar()
loadFgProgressBar()
}
fileprivate func loadFgProgressBar() {
let startAngle = CGFloat(-Double.pi / 2)
let endAngle = CGFloat(3 * Double.pi / 2)
let centerPoint = CGPoint(x: frame.width/2 , y: frame.height/2)
let gradientMaskLayer = gradientMask()
fgProgressLayer.path = UIBezierPath(arcCenter:centerPoint, radius: frame.width/2 - 30.0, startAngle:startAngle, endAngle:endAngle, clockwise: true).cgPath
fgProgressLayer.backgroundColor = UIColor.clear.cgColor
fgProgressLayer.fillColor = nil
fgProgressLayer.strokeColor = UIColor.black.cgColor
fgProgressLayer.lineWidth = 4.0
fgProgressLayer.strokeStart = 0.0
fgProgressLayer.strokeEnd = 0.0
gradientMaskLayer.mask = fgProgressLayer
layer.addSublayer(gradientMaskLayer)
}
fileprivate func gradientMask() -> CAGradientLayer {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.locations = [0.0, 1.0]
let colorTop: AnyObject = CustomColor.lime.cgColor
let colorBottom: AnyObject = CustomColor.lime.cgColor
let arrayOfColors: [AnyObject] = [colorTop, colorBottom]
gradientLayer.colors = arrayOfColors
return gradientLayer
}
fileprivate func loadBgProgressBar() {
let startAngle = CGFloat(-Double.pi / 2)
let endAngle = CGFloat(3 * Double.pi / 2)
let centerPoint = CGPoint(x: frame.width/2 , y: frame.height/2)
let gradientMaskLayer = gradientMaskBg()
bgProgressLayer.path = UIBezierPath(arcCenter:centerPoint, radius: frame.width/2 - 30.0, startAngle:startAngle, endAngle:endAngle, clockwise: true).cgPath
bgProgressLayer.backgroundColor = UIColor.clear.cgColor
bgProgressLayer.fillColor = nil
bgProgressLayer.strokeColor = UIColor.black.cgColor
bgProgressLayer.lineWidth = 4.0
bgProgressLayer.strokeStart = 0.0
bgProgressLayer.strokeEnd = 1.0
gradientMaskLayer.mask = bgProgressLayer
layer.addSublayer(gradientMaskLayer)
}
fileprivate func gradientMaskBg() -> CAGradientLayer {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = bounds
gradientLayer.locations = [0.0, 1.0]
let colorTop: AnyObject = CustomColor.strawberry.cgColor
let colorBottom: AnyObject = CustomColor.strawberry.cgColor
let arrayOfColors: [AnyObject] = [colorTop, colorBottom]
gradientLayer.colors = arrayOfColors
return gradientLayer
}
uj5u.com熱心網友回復:
通過在 layoutSubViews 函式中加載背景和前景進度條來解決問題。
ProgressBar.swift
import UIKit
import Pulsator
class ProgressBar: UIView, CAAnimationDelegate {
fileprivate var animation = CABasicAnimation()
fileprivate var animationDidStart = false
fileprivate var updatedAnimationAdded = false
fileprivate var updateExecuted = false
fileprivate var totalTimerDuration = 0
fileprivate var isProgressBarAdded:Bool = false
fileprivate var barlineWidth: CGFloat = 8
// let pulsator = Pulsator()
// fileprivate var width: CGFloat
// fileprivate var height: CGFloat
//
lazy var fgProgressLayer: CAShapeLayer = {
let fgProgressLayer = CAShapeLayer()
return fgProgressLayer
}()
lazy var bgProgressLayer: CAShapeLayer = {
let bgProgressLayer = CAShapeLayer()
return bgProgressLayer
}()
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
loadBgProgressBar()
loadFgProgressBar()
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override func layoutSubviews() {
super.layoutSubviews()
if self.frame.width > 0 && self.frame.height > 0 && isProgressBarAdded == false {
loadBgProgressBar()
loadFgProgressBar()
isProgressBarAdded = true
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/372039.html
