注意
このハック的にブラー調整する方法ですが、
一回アプリを離れてホームに戻ってからアプリを再度開いた場合など
再描画が走るタイミングで、ブラーエフェクトが消えてしまいます。
僕の方では解決する方法が見つからなかったため、開発していたアプリに組み込むのは断念しました。
プロダクトの実装で使用する際はお気をつけください。
注意2
iOS 11.0.2 で試していたのですが、
UIViewAnimating::pauseAnimation()
を走らせた段階でクラッシュする現象が起きてしまいました。
仕様なのかバグなのか不明ですが、現状使えなさそうです。
環境
- iOS10
やりたいこと
Storyborad上で置いた UIVisualEffectView
にかかってるブラーエフェクトのかかり具合を調節したい。
かかってないところから調節したところまで、フェードインアニメーションをさせたい。
できたもの
UIVisualEffectViewのエクステンションとして作るとこのような感じ
extension UIVisualEffectView {
/**
ブラーのかかり具合を調整
(Storyboard等でブラーエフェクトが指定されてる前提)
- parameter radius: 0.0 - 1.0
- parameter setAlphaZero: alphaを0にするかどうか
*/
func setBlurEffectRadius(_ radius: CGFloat = 0.3, setAlphaZero: Bool = false) {
let anim = UIViewPropertyAnimator(duration: 1, curve: .linear) {
self.effect = nil
}
// startしないと、fractionCompleteの状態の描画がされないので走らせる
anim.startAnimation()
anim.pauseAnimation()
// ブラーのアニメーション位置指定をすることで、かかり具合を調節する
anim.fractionComplete = 1 - radius
if setAlphaZero {
self.alpha = 0
}
}
/**
alpha値をアニメーションで1にする
- parameter duration: アニメーション時間
*/
func startFadeInAnimation(_ duration: TimeInterval = 1) {
UIView.animate(withDuration: duration, delay: 0, options: .curveEaseInOut, animations: {
self.alpha = 1
}, completion: nil)
}
}
PlaygroundsプロジェクトをGithubにあげました: https://github.com/umeruma/BlurAnimationDemo
Playgroundsファイルをzipアーカイブしたリンク先こちら
https://github.com/umeruma/BlurAnimationDemo/blob/master/BlurAnimationDemo.playground.zip?raw=true
(iPadユーザーでPlaygroundsアプリ使ってる方、
リンクから、直接iPadにPlaygroundプロジェクトをダウンロードできます。)
やったこと
UIVisualEffect
のブラーのかかり具合を調節するメソッドやプロパティーは用意されてない。
でも、アニメーション用メソッドを使って無理やり?ブラーの調節ができる。
こちらの記事だと、スライダーの値(0-1)をアニメーションの経過タイミングに指定することで、ブラーのかかり具合を調節してる。
スライダーなしにブラーのかかり具合を調節したいので、単純に、
let anim = UIViewPropertyAnimator(duration: 1, curve: .linear) {
self.visualEffectView.effect = nil
}
anim.fractionComplete = 0.6
としてみるも、なぜか反映されない。
なんでだろうと思っていたら、
swift - Animate the fractionComplete of UIViewPropertyAnimator for blurring the background
こちらのStackoverflowの回答にあるように、どうやらUIViewPropertyAnimator
のアニメーションを走らせないと、.fractionComplete
の値を変更してもViewの更新がされないとのこと。
てことで、回答にならって書いたら、ブラーの調整が反映された。
調節ができので、ブラーがかかってないところから任意のところまでブラーがかかるアニメーションを実装してみたのがこちら
// Storyborad上に置いてあるUIVisualEffectViewにつないでます
@IBOutlet weak var visualEffectView: UIVisualEffectView
// MARK: - ここからは viewDidLoad() 内とかに書く
// ブラー調節用のアニメーター作成
let anim = UIViewPropertyAnimator(duration: 1, curve: .linear) {
self.visualEffectView.effect = nil
}
// startしないとfractionComplete指定しても動かないので走らせる
anim.startAnimation()
// ですぐ止める
anim.pauseAnimation()
// そして明示的に指定すると、反映される
anim.fractionComplete = 0.6
// Viewの透明度0にしておく
visualEffectView.alpha = 0
// MARK: - ビューが表示した後アニメーション走らせたいので、下記はviewDidAppear(animated:) 内とかに書く
// アニメーションで透明度を変更する
UIView.animate(withDuration: 3, delay: 0, options: .curveEaseInOut, animations: {
self.overlayEffectView.alpha = 1
}, completion: nil)
透明度を変更してアニメーションさせると、アニメーション中にかかってるブラーが消えるんじゃないかと思ったんだけど、消えてないように見える。