애니메이션을 통해 UIView를 회전하여 각도를 얻는 방법

19146 단어 Swift

하고 싶은 일


3
  • 아래에 표시된 호(UIView)를 애니메이션으로 회전하려고 합니다.
    [Swift] 원호의 묘사 방법
  • 4
  • 정지할 때 호의 각도를 원합니다
  • 이미지



    1. 애니메이션을 사용하여 UIView 회전


    ViewController.swift
    
    var animation: CABasicAnimation = CABasicAnimation()
    
    // animation の設定
    animation = CABasicAnimation(keyPath: "transform.rotation")
    animation.isRemovedOnCompletion = true
    animation.fillMode = CAMediaTimingFillMode.forwards
    animation.fromValue = 0
    // 1回のアニメーションで、360度まで回転する。
    animation.toValue = CGFloat(Double.pi / 180) * 360
    // 回転速度
    animation.duration = 2.0
    // リピート回数
    animation.repeatCount = .infinity
    
    pathDrawView.layer.add(animation, forKey: "animation")
    
    

    2. 각도를 위한 애니메이션 중지


    이쪽 기사를 참고하게 해 주세요.
    Getting the rotation angle after CABasicAnimation?
    
    // 一時停止
    func stopRotate() {
        let layer = pathDrawView.layer
    
        // 角度を取得する
        let transform: CATransform3D = layer.presentation()!.transform
        let angle: CGFloat = atan2(transform.m12, transform.m11)
        var testAngle = radiansToDegress(radians: angle) + 90
        if testAngle < 0 {
            testAngle = 360 + testAngle
        }
    
        print("角度", testAngle)
        angleLabel.text = String("\(Int(testAngle))°")
    
        // アニメーションを停止する
        layer.speed = 0.0       
    }
    
    func radiansToDegress(radians: CGFloat) -> CGFloat {
        return radians * 180 / CGFloat(Double.pi)
    }
    
    

    전체 코드


    ViewController.swift
    
    import UIKit
    
    class ViewController: UIViewController {
    
        @IBOutlet weak var arkBackgroundView: UIView!
        @IBOutlet weak var switchButton: UIButton!
        @IBOutlet weak var angleLabel: UILabel!
    
        var pathDrawView = PathDraw()
        var isRotate = true
        var animation: CABasicAnimation = CABasicAnimation()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            switchButton.setTitle("STOP", for: .normal)
    
            pathDrawView = PathDraw(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
            // isOpaque 背景を透明にする。デフォルトは黒色。
            pathDrawView.isOpaque = false
            arkBackgroundView.addSubview(pathDrawView)
    
            // animation の設定
            animation = CABasicAnimation(keyPath: "transform.rotation")
            animation.isRemovedOnCompletion = true
            animation.fillMode = CAMediaTimingFillMode.forwards
            // 0度から回転を開始する。
            animation.fromValue = 0
            // 1回のアニメーションで、360度まで回転する。
            animation.toValue = CGFloat(Double.pi / 180) * 360
            // 回転速度
            animation.duration = 2.0
            // リピート回数
            animation.repeatCount = .infinity
    
            pathDrawView.layer.add(animation, forKey: "animation")
        }
    
        // 一時停止
        func stopRotate() {
            let layer = pathDrawView.layer
    
            // 角度を取得する
            let transform: CATransform3D = layer.presentation()!.transform
            let angle: CGFloat = atan2(transform.m12, transform.m11)
            var testAngle = radiansToDegress(radians: angle) + 90
            if testAngle < 0 {
                testAngle = 360 + testAngle
            }
    
            print("角度", testAngle)
            angleLabel.text = String("\(Int(testAngle))°")
    
            // 現在時刻を layer の timeOffset プロパティに設定
            let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil)
            layer.timeOffset = pausedTime
    
            // アニメーションを停止する
            layer.speed = 0.0
        }
    
        func radiansToDegress(radians: CGFloat) -> CGFloat {
            return radians * 180 / CGFloat(Double.pi)
        }
    
        // 再開
        func restartRotate() {
            let layer = pathDrawView.layer
    
            // 一時停止した時の時刻
            let pausedTime = layer.timeOffset
    
            // アニメーションを再開する
            layer.speed = 1.0
    
            // layer の timeOffset プロパティに 0 を設定
            layer.timeOffset = 0.0
    
            // beginTimeプロパティはアニメーションの開始時刻を表します。
            layer.beginTime = 0.0
    
            // 現在時刻 - 一時停止した時の時刻
            let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
            layer.beginTime = timeSincePause
        }
    
        @IBAction func SpinButtonTapped(_ sender: Any) {
            if isRotate {
                switchButton.setTitle("START", for: .normal)
                stopRotate()
                print("stop!!")
                isRotate = false
    
            } else {
                switchButton.setTitle("STOP", for: .normal)
                restartRotate()
                print("restart!")
                isRotate = true
            }
        }
    }
    
    
    

    참고 자료


    Getting the rotation angle after CABasicAnimation?
    Apple 공식 참조 CABasicAnimation

    좋은 웹페이지 즐겨찾기