まず、提示されたコードだとapplicationDidEnterBackground()
内で新たにKenteiViewController
を作ってしまっているため、アニメーションの停止自体ができていません。
すでに存在しているオブジェクトがあるはずなのでそちらのtimerbarstop()
を呼び出すようにしなければ意味がありません。
その修正をしてもアニメーションが消えるのは変わりません。
バックグラウンドに行くとアニメーションが消えてしまうからみたいです。(知らなかった…)
それの回答ですがやっぱり StackOverflow にあります。
簡単に言うと、バックグラウンドに行く時(applicationDidEnterBackground()
)にanimationForKey()
でCAAnimationオブジェクトをメンバ変数等に保存しておいて、フォアグラウンドに復帰する際(applicationWillEnterForeground()
)に再度 addAnimation(forKey:)
で追加し直してあげればいいです。
6/26追記
一応動かせるコードを載せます。
AppDelegateからViewControllerを探すのは面倒ですし画面構成によって探し方も変わるのでViewController内で通知を受信してアニメーションをポーズさせるように変更しました。
アニメーション開始のコードがなかったのでviewDidAppearでとりあえず開始するようにしました。
scHeiとscWidってなんなのかわかんなかったのでとりあえず画面サイズっぽい値を入れてみました。
Swift
1 KenteiViewController . swift
2
3 class KenteiViewController : UIViewController {
4
5 private var myImageView : UIImageView !
6 var pausedAnimations : [ String : CAAnimation ] ?
7
8 override func viewDidLoad ( ) {
9 super . viewDidLoad ( )
10
11 // バックグラウンドへ遷移する通知の受信開始
12 NSNotificationCenter . defaultCenter ( ) . addObserver ( self , selector : # selector ( KenteiViewController . didEnterBackgroundNotification ( _ : ) ) , name : UIApplicationDidEnterBackgroundNotification , object : nil )
13 // バックグラウンドから復帰する通知の受信開始
14 NSNotificationCenter . defaultCenter ( ) . addObserver ( self , selector : # selector ( KenteiViewController . willEnterForegroundNotification ( _ : ) ) , name : UIApplicationWillEnterForegroundNotification , object : nil )
15 }
16
17 deinit {
18 // バックグラウンドへ遷移する通知の受信解除
19 NSNotificationCenter . defaultCenter ( ) . removeObserver ( self , name : UIApplicationDidEnterBackgroundNotification , object : nil )
20 // バックグラウンドから復帰する通知の受信解除
21 NSNotificationCenter . defaultCenter ( ) . removeObserver ( self , name : UIApplicationWillEnterForegroundNotification , object : nil )
22 }
23
24 // バックグラウンドへ遷移する通知受信時の処理
25 func didEnterBackgroundNotification ( notification : NSNotification ) {
26 guard let myImageView = myImageView else { return }
27
28 // myImageViewのレイヤに設定されているCAAnimationオブジェクトをpausedAnimationsに保持する
29 var animations = [ String : CAAnimation ] ( )
30 myImageView . layer . animationKeys ( ) ? . forEach ( { ( key ) in
31 animations [ key ] = myImageView . layer . animationForKey ( key )
32 } )
33 if ! animations . isEmpty {
34 pausedAnimations = animations
35 pauseLayer ( myImageView . layer )
36 }
37 }
38
39 // バックグラウンドから復帰する通知受信時の処理
40 func willEnterForegroundNotification ( notification : NSNotification ) {
41 guard let myImageView = myImageView else { return }
42
43 if let animations = pausedAnimations {
44 // pausedAnimationsに保持していたCAAnimationオブジェクトをmyImageViewのレイヤに追加し直す
45 animations . forEach ( { ( key , animation ) in
46 myImageView . layer . addAnimation ( animation , forKey : key )
47 } )
48 self . pausedAnimations = nil
49 resumeLayer ( myImageView . layer )
50 }
51 }
52
53 override func viewDidAppear ( animated : Bool ) {
54 super . viewDidAppear ( animated )
55
56 // とりあえずココでアニメーション開始
57 timerbar ( )
58 }
59
60 // よくわかんないので画面サイズっぽい値にする
61 let scHei : CGFloat = 480.0
62 let scWid : CGFloat = 320.0
63
64 func timerbar ( ) {
65 let barHeight = scHei * 0.011
66 let barWidth = scWid * 0.58
67 let barXPosition = scWid * 0.14
68 let barYPosition = scHei * 0.367
69 let barXPositionEnd = barXPosition + barWidth
70 // UIImageViewを作成する.
71 myImageView = UIImageView ( )
72 // 表示する画像を設定する.
73 let myImage = UIImage ( named : "jikanbar.jpg" )
74 // 画像をUIImageViewに設定する.
75 myImageView . image = myImage
76 // 画像の表示する座標を指定する.
77 myImageView . frame = CGRectMake ( barXPosition , barYPosition , barWidth , barHeight )
78 // UIImageViewをViewに追加する.
79 self . view . addSubview ( myImageView )
80
81 UIView . animateWithDuration ( 20 , delay : 0.0 , options : UIViewAnimationOptions . CurveLinear , animations : { ( ) - > Void in
82 self . myImageView . frame = CGRectMake ( barXPositionEnd , barYPosition , 0 , barHeight )
83 } , completion : { ( finished : Bool ) - > Void in
84 // アニメーション終了後の処理
85 } )
86
87 }
88
89 func pauseLayer ( layer : CALayer ) {
90 let pausedTime = layer . convertTime ( CACurrentMediaTime ( ) , fromLayer : nil )
91 layer . speed = 0.0
92 layer . timeOffset = pausedTime
93 }
94
95 func resumeLayer ( layer : CALayer ) {
96 let pausedTime = layer . timeOffset
97 layer . speed = 1.0
98 layer . timeOffset = 0.0
99 layer . beginTime = 0.0
100 let timeSincePause = layer . convertTime ( CACurrentMediaTime ( ) , fromLayer : nil ) - pausedTime
101 layer . beginTime = timeSincePause
102 }
103 }
104
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。