質問: labelも100回繰り返されていることになっていますよね・・・。 その場合、どうしたらいいのでしょうか。 今は辞書キーがnilじゃなかったら更新を1秒に100回繰り返していますが、 1度変わってしまえば残り99回は必要ありませんし、そうすればアニメーションも正常に機能すると思うのです・・・。 つまり、**辞書キーがnilじゃないとき、1度のみUILabelの表示を更新してそのときアニメーションを実行、また別のキーと値が取り出せたらそれも一回のみUILabelの表示の更新とアニメーション**という処理をしたいということでした。
回答: すでにご質問の中で根本的な原因が記載されていますが、秒部分までをキーとして0.01秒ごとに一致するキーがあるかどうかをチェックしているので、時間が一致している間の1秒間、およそ100回アニメーションを実施している、という状態になっています。 アニメーションの開始タイミングを`player`の現在再生時間(`currentPlaybackTime`)に同期させたいという要求があるようですので、適当な時間でポーリングを行うのは仕方ないところでしょうから、単純に「1回アニメーションを始めたら、時間が変わるまで次のアニメーションは始めない」と言うチェックを入れるのが、簡単で確実だろうと思います。 (ちなみにポーリングの間隔は0.1秒程度でもほとんどの普通の人には違和感がないと思いますが。) ``` //最後にアニメーションしたタイミング var lastTimeKey = "--:--" func labelUpdate() { let min = Int(player.currentPlaybackTime) / 60 let sec = Int(player.currentPlaybackTime.truncatingRemainder(dividingBy: 60)) let timeKey = String(format: "%02d:%02d", min, sec) //タイミングが変わった時だけアニメーションすべきかどうかチェックを入れる if timeKey != lastTimeKey, let label = testDict[timeKey] { let anime = CATransition() anime.type = kCATransitionMoveIn anime.subtype = kCATransitionFromBottom anime.duration = 0.2 testLabel.layer.add(anime, forKey: nil) testLabel.text = label //最後にアニメーションしたタイミングを覚えておく lastTimeKey = timeKey } } ``` もちろん`lastTimeKey`の値は`player.currentPlaybackTime`がリセットされるような操作をした場合には、再度初期値に戻しておく必要があります。 他にももっと良い方法があるかもしれません。ご自身でより良い方法を見つけられた場合には、遠慮なさらず是非とも回答の形で投稿していただければと思います。