当前位置: 首页 > 知识库问答 >
问题:

我如何多次使用相同的按钮和动作,但影响图层而不是视图

富涛
2023-03-14

我试图在每个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)
    }
}

这是运行代码时发生的情况的图片。当我单击任何图片按钮时,它不是在我按下的任何按钮上运行进度条动画,而是只在最后添加到视图控制器的按钮上运行它。

共有1个答案

微生俊捷
2023-03-14

不要在视图控制器中使用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()中的circle函数。问题是,您的动画影响了您的视图(而不是单个圆圈),通过为circle按钮创建一个类,您可以在SecondViewController中调用它,它将只影响按下按钮的圆圈。

 类似资料:
  • 我有一个表单,在那里,我想使用图像而不是单选按钮。我如何显示多个图像,而不是单选按钮。例如,性别与“男性” 但在这里,问题出现了,当我将输入id更改为其他名称时,它不起作用。有人能帮我吗,因为这是一个非常简单的方法,我想用这个。您可以将输入id更改为“visa1”,然后查看结果。

  • 问题内容: 我有以下接口,我想在类中多次实现: 现在,我希望能够通过以下方式实现此接口: 但是,这给了我错误:在行上: 是否可以使用不同的泛型两次实现接口?如果不是,那么我在这里可以做的下一步工作是什么? 问题答案: 您需要使用内部或匿名类。例如:

  • 我是Android开发新手,所以我只想问一下,我该如何把这些事情做好。我已经做了一个杂货清单应用程序,将显示数量,项目名称和状态(复选框)。以下是我的问题: 列表上的项目或项目名称未显示 如果我有这么多问题,我很抱歉,如果你能帮我回答这些问题,我将不胜感激。谢谢!:) 杂货模型类 GroceryList活动 数组接口 我的XML文件

  • 首先,我仍然是Android开发的新手,我以前在这里问过类似的问题,如何让我的片段利用我的活动数据?以及如何将数据从活动发送到片段?(Android)但似乎大多数人都不太明白我的意思,所以让我来解释一下。假设我有一个文本视图: 和一个按钮: 在我的第一个片段layout.xml中,然后我想从我的主活动中调用它们,即以获取数据,即从天气API和。Android Studio不允许您这样使用它们,所以

  • 问题内容: 我正在制作一个平台游戏,当你按下空格键时,角色会射击一个火球,该火球会在屏幕上移动,但是当你再次按下空格键时,该火球的坐标将重新设置为玩家的坐标,而不是绘制我想要的另一个火球。 问题答案: 是正确的。你需要某种数据结构来容纳火球。在下面的示例中,我使用List的Fireball。 要绘制它们,我只是遍历它们。为了使它们向前移动,我只是增加了计时器中的x值,然后调用重绘 这是完整的代码

  • 问题内容: 我有一个网站开始,我希望有2个单独的提交按钮,其中一个将获取输入的数据并对其进行一些计算以显示在同一屏幕上。我已经成功地与以下人员合作: 然后我用: 现在,我想要第二个提交按钮,该按钮仍然可以捕获他们输入的数据,然后转到另一个地址。有没有一种优雅的方法可以做到这一点? 问题答案: 您可以将方法添加到新的提交按钮,该方法将更改表单的操作,然后提交。