【问题标题】:How can I use the same button and action multiple times, but affect the layer instead of the view如何多次使用相同的按钮和操作,但影响图层而不是视图
【发布时间】:2021-07-13 16:20:39
【问题描述】:

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

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

【问题讨论】:

    标签: ios swift


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多