ios - 如何多次使用相同的按钮和操作,但影响图层而不是视图
问题描述
我试图在每个createCircle()
功能中使用相同的按钮,但是当我按下按钮并运行该handleTap()
功能时,它仅适用于最近添加的圆圈。我想使用相同的按钮,但是当我单击单个按钮时,它应该在我按下的那个按钮上运行动画。
import UIKit
class SecondViewController: UIViewController {
let shapeLayer = CAShapeLayer()
let percentageLabel: UILabel = {
let label = UILabel()
label.text = ""
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 28)
label.textColor = UIColor(red: 0.59, green: 0.42, blue: 0.23, alpha: 1.00)
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
_ = createCircle(positionX: 100, positionY: 200)
_ = createCircle(positionX: 100, positionY: 375)
_ = createCircle(positionX: 100, positionY: 550)
_ = createCircle(positionX: 100, positionY: 725)
_ = createCircle(positionX: 300, positionY: 200)
_ = createCircle(positionX: 300, positionY: 375)
_ = createCircle(positionX: 300, positionY: 550)
_ = createCircle(positionX: 300, positionY: 725)
}
//MARK: - Create Circle
func createCircle(positionX: Int, positionY: Int) -> (CGPoint) {
let trackLayer = CAShapeLayer()
let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
button.layer.cornerRadius = 0.5 * button.bounds.size.width
button.clipsToBounds = true
button.center = view.center
button.addTarget(self, action: #selector(handleTap), for: .touchUpInside)
view.addSubview(button)
let circularPath = UIBezierPath(arcCenter: .zero, radius: 50, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = UIColor(red: 0.82, green: 0.69, blue: 0.52, alpha: 1.00).cgColor
trackLayer.fillColor = UIColor.clear.cgColor
trackLayer.lineWidth = 10
trackLayer.position = CGPoint(x: positionX, y: positionY)
view.layer.addSublayer(trackLayer)
shapeLayer.path = circularPath.cgPath
shapeLayer.strokeColor = UIColor(red: 0.59, green: 0.42, blue: 0.23, alpha: 1.00).cgColor
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineWidth = 10
shapeLayer.lineCap = CAShapeLayerLineCap.round
shapeLayer.position = CGPoint(x: positionX, y: positionY)
shapeLayer.transform = CATransform3DMakeRotation(-CGFloat.pi / 2, 0, 0, 1)
view.addSubview(percentageLabel)
percentageLabel.frame = CGRect(x: 0, y: 0, width: 150, height: 150)
percentageLabel.center = CGPoint(x: positionX, y: positionY)
return CGPoint(x: positionX, y: positionY)
}
//MARK: - Tap function
var done = 0
var toDo = 0
@objc func handleTap(sender: UIButton) {
toDo = 5
if done < toDo {
done += 1
} else {
done -= toDo
}
let percentage = CGFloat(done) / CGFloat(toDo)
percentageLabel.text = "\(Int(percentage * 100))%"
DispatchQueue.main.async {
self.shapeLayer.strokeEnd = percentage
}
view.layer.addSublayer(shapeLayer)
}
}
这是我运行代码时发生的情况的图片。当我单击任何图中的按钮时,不是在我按下的任何按钮上运行进度条动画,它只在最后添加到视图控制器的按钮上运行它。
解决方案
不要createCircle()
在您的视图控制器中使用,而是为其创建一个新文件并在内部像这样初始化函数。
import UIKit
class Button: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
createCircle()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let percentageLabel: UILabel = {
let label = UILabel()
label.text = ""
label.textAlignment = .center
label.font = UIFont.boldSystemFont(ofSize: 28)
label.textColor = UIColor(red: 0.59, green: 0.42, blue: 0.23, alpha: 1.00)
return label
}()
let shapeLayer = CAShapeLayer()
func createCircle() {
let trackLayer = CAShapeLayer()
let button = UIButton(type: .custom)
button.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
button.layer.cornerRadius = 0.5 * button.bounds.size.width
button.clipsToBounds = true
button.center = center
button.addTarget(self, action: #selector(handleTap), for: .touchUpInside)
addSubview(button)
let circularPath = UIBezierPath(arcCenter: .zero, radius: 50, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)
trackLayer.path = circularPath.cgPath
trackLayer.strokeColor = UIColor(red: 0.82, green: 0.69, blue: 0.52, alpha: 1.00).cgColor
trackLayer.fillColor = UIColor.clear.cgColor
trackLayer.lineWidth = 10
trackLayer.position = center
layer.addSublayer(trackLayer)
shapeLayer.path = circularPath.cgPath
shapeLayer.strokeColor = UIColor(red: 0.59, green: 0.42, blue: 0.23, alpha: 1.00).cgColor
shapeLayer.fillColor = UIColor.clear.cgColor
shapeLayer.lineWidth = 10
shapeLayer.lineCap = CAShapeLayerLineCap.round
shapeLayer.position = center
shapeLayer.transform = CATransform3DMakeRotation(-CGFloat.pi / 2, 0, 0, 1)
addSubview(percentageLabel)
percentageLabel.frame = CGRect(x: 0, y: 0, width: 150, height: 150)
// percentageLabel.center = CGPoint(x: positionX, y: positionY)
// return CGPoint(x: positionX, y: positionY)
}
var done = 0
var toDo = 0
@objc func handleTap(sender: UIButton) {
toDo = 5
if done < toDo {
done += 1
} else {
done -= toDo
}
let percentage = CGFloat(done) / CGFloat(toDo)
percentageLabel.text = "\(Int(percentage * 100))%"
DispatchQueue.main.async {
self.shapeLayer.strokeEnd = percentage
}
layer.addSublayer(shapeLayer)
}
}
您可以从您的按钮中删除secondViewController
与您的按钮有关的代码,并在您的viewDidLoad()
. 问题是您的动画正在影响您的视图(而不是单个圆圈),通过为您的圆圈按钮创建一个类,您可以在您的中调用它,secondViewController
它只会影响按下按钮的圆圈。
推荐阅读
- javascript - 在哪里发送请求,父组件或子组件?
- excel - SUMPRODUCT 代码错误。我得到了#VALUE!错误
- python - 如何根据多列的值拆分数据框
- node.js - 我可以在 socket.io 中创建群组和私人聊天应用吗
- python - Zerorpc 异步调用
- google-apps-script - Google 协作平台应用脚本不适用于自定义域
- vba - 检查 7-Zip (64 / 32bit) 的正确安装
- c++ - 如何在 vim 的颜色方案文件中更改运算符 (+ - * / < >) 的颜色
- asp.net-core - ASP.Net Core 2 忽略本地主机请求的 JWT 授权
- symfony - 根据复选框按钮显示字段