質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

2420閲覧

CABasicAnimationを一時停止したい

syoco0330

総合スコア30

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/08/10 03:27

SwiftでiOSアプリのインターバルタイマーアプリを開発しています。
イメージ説明

一時停止をした時に、タイマーの数字は止めれるのですが、
円のアニメーションが止まりません。

どのように実装したらよろしいでしょうか?
stop()の部分でタイマーとアニメーションを止めたいと思っています。

ご教授いただけると幸いです。
よろしくお願いいたします。

swift

1 2import UIKit 3 4@objc protocol CountDownDelegate { 5 func didCount(count:Int) 6 func didFinish() 7} 8 9 10class CountDownView: UIView, CAAnimationDelegate { 11 12 weak var delegate: CountDownDelegate? 13 14 var shapeLayer = CAShapeLayer() 15 var label = UILabel() 16 var max = 0 17 var timer: Timer? 18 19 20 override init(frame: CGRect) { 21 super.init(frame: frame) 22 } 23 24 required init?(coder aDecoder: NSCoder) { 25 fatalError("init(coder:) has not been implemented") 26 } 27 28 override func layoutSubviews() { 29 print("DEBUG_PRINT: layoutSubviewsが呼ばれました") 30 let lineWidth:CGFloat = 10.0 31 //let lineColor = UIColor.black 32 33 shapeLayer.isHidden = true 34 label.isHidden = true 35 shapeLayer.frame = CGRect(x: 0, y: 0, width: frame.width, height: frame.height) 36 shapeLayer.fillColor = UIColor.clear.cgColor 37 shapeLayer.strokeColor = UIColor.black.cgColor 38 shapeLayer.lineWidth = lineWidth 39 40 let center = CGPoint(x: bounds.size.width / 2.0, y: bounds.size.height / 2.0) 41 let radius = bounds.size.width 42 let startAngle = CGFloat(-M_PI_2) 43 let endAngle = startAngle + 2.0 * CGFloat(M_PI) 44 let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true) 45 shapeLayer.path = path.cgPath 46 layer.addSublayer(shapeLayer) 47 48 label.frame = CGRect(x: 0, y: 0, width: frame.width * 2, height: frame.height * 2) 49 label.center = CGPoint(x: bounds.size.width / 2.0, y: bounds.size.height / 2.0) 50 label.textAlignment = NSTextAlignment.center 51 // 文字のガタつきを解消 52 label.font = UIFont.monospacedDigitSystemFont(ofSize: 50, weight: .heavy) 53 //label.font = UIFont.init(name: "DBLCDTempBlack", size: 50) 54 addSubview(label) 55 } 56 57 func start(max:Int, timeColor: String) { 58 print("DEBUG_PRINT: start (max)") 59 if self.timer == nil { 60 self.timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(count(_:)), userInfo: nil, repeats: true) 61 } 62 animation(max) 63 self.max = max 64 label.text = "(max)" 65 shapeLayer.isHidden = false 66 label.isHidden = false 67 68 switch timeColor { 69 case "jyunbi": 70 shapeLayer.strokeColor = UIColor.systemYellow.cgColor 71 label.textColor = UIColor.systemYellow 72 case "undou": 73 shapeLayer.strokeColor = UIColor.systemRed.cgColor 74 label.textColor = UIColor.systemRed 75 case "kyukei": 76 shapeLayer.strokeColor = UIColor.systemBlue.cgColor 77 label.textColor = UIColor.systemBlue 78 default: 79 shapeLayer.strokeColor = UIColor.black.cgColor 80 label.textColor = UIColor.blue 81 } 82 83 } 84 85 @objc func count(_ timer: Timer) { 86 print("DEBUG_PRINT: countが始まりました") 87 print(max) 88 if self.max != 0 { 89 print("DEBUG_PRINT: (max)") 90 self.max -= 1 91 label.text = "(max)" 92 } else if max == 0 { 93 print("aaa") 94 if self.timer != nil { 95 self.timer?.invalidate() 96 self.timer = nil 97 } 98 } 99 100 101 } 102 103 func animation(_ max: Int) { 104 print("animationが呼ばれました") 105 let animation = CABasicAnimation(keyPath: "strokeEnd") 106 animation.duration = CFTimeInterval(max) 107 animation.fromValue = 1.0 108 animation.toValue = 0.0 109 animation.delegate = self 110 shapeLayer.add(animation, forKey: "circleAnim") 111 } 112 113 114 // タイマーとアニメーションを止める 115 func stop() { 116 print("DEBUG_PRINT: stopが呼ばれました") 117 if self.timer != nil { 118 self.timer?.invalidate() 119 self.timer = nil 120 121 } 122 } 123 124 125 func reset() { 126 shapeLayer.isHidden = true 127 shapeLayer.removeAnimation(forKey: "circleAnim") 128 } 129 130 func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { 131 print("DEBUG_PRINT: animationDidStopが呼ばれました") 132 delegate?.didFinish() 133 134 } 135} 136

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

StackOverflow からの引用ほぼそのまま(メソッド名の書き換えのみ)ですが、下記の例の方が一時停止も再開もやりやすそうに感じました(初回の回答はアニメーションそのものを削除するため)。

Swift

1 func pauseAnimation(){ 2 let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil) 3 layer.speed = 0.0 4 layer.timeOffset = pausedTime 5 } 6 7 func resumeAnimation(){ 8 let pausedTime = layer.timeOffset 9 layer.speed = 1.0 10 layer.timeOffset = 0.0 11 layer.beginTime = 0.0 12 let timeSincePause = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime 13 layer.beginTime = timeSincePause 14 }

###元の回答

アニメーションを完全に止めるのであれば、こんな感じでいかがでしょうか。

Swift

1 // タイマーとアニメーションを止める 2 func stop() { 3 print("DEBUG_PRINT: stopが呼ばれました") 4 if self.timer != nil { 5 self.timer?.invalidate() 6 self.timer = nil 7 8 } 9 10 // MARK: アニメーションを止める 11 if let strokeEnd = shapeLayer.presentation()?.strokeEnd { 12 shapeLayer.removeAnimation(forKey: "circleAnim") 13 // removeAnimation(forkey:)だけだと、アニメーションが元に戻るので、止める直前の状態に設定する 14 shapeLayer.strokeEnd = strokeEnd 15 } 16 }

投稿2020/08/10 05:10

編集2020/08/11 03:09
TsukubaDepot

総合スコア5086

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

syoco0330

2020/08/10 11:48

ありがとうございます! 上記コードの追記と下記を追記して一時停止の実装ができました。 var isDelegate = false func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { print("DEBUG_PRINT: animationDidStopが呼ばれました") // 一時停止の場合の処理 if isDelegate != false { isDelegate = false return } delegate?.didFinish() }
syoco0330

2020/08/10 11:50

ちなみにですが、 一時停止の再開の処理を実装しようと奮闘しているのですが、 どのように実装したらよろしいでしょうか? shapeLayer.strokeStart で実装するのではないかと思って色々試しているのですが、うまくいかないです。。。
TsukubaDepot

2020/08/11 03:09

StackOverflowで使えそうな回答を見つけましたので、本文に転載しました。ご確認ください。
syoco0330

2020/08/11 12:53

一時停止と再開の実装ができました。 大変助かりました。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問