LoginSignup
15
20

More than 5 years have passed since last update.

Storyboard上で置いてるUIVisualEffectViewのブラーのかかり具合を調節、アニメーションさせる [iOS10]

Last updated at Posted at 2017-03-29

注意

このハック的にブラー調整する方法ですが、
一回アプリを離れてホームに戻ってからアプリを再度開いた場合など
再描画が走るタイミングで、ブラーエフェクトが消えてしまいます。

僕の方では解決する方法が見つからなかったため、開発していたアプリに組み込むのは断念しました。

プロダクトの実装で使用する際はお気をつけください。

注意2

iOS 11.0.2 で試していたのですが、

UIViewAnimating::pauseAnimation()

を走らせた段階でクラッシュする現象が起きてしまいました。
仕様なのかバグなのか不明ですが、現状使えなさそうです。

環境

  • iOS10

やりたいこと

Storyborad上で置いた UIVisualEffectView にかかってるブラーエフェクトのかかり具合を調節したい。
かかってないところから調節したところまで、フェードインアニメーションをさせたい。

できたもの

UIVisualEffectViewのエクステンションとして作るとこのような感じ

UIVisualEffectView+Blur.swift
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

iPad Playgrounds Capture

Playgroundsファイルをzipアーカイブしたリンク先こちら
https://github.com/umeruma/BlurAnimationDemo/blob/master/BlurAnimationDemo.playground.zip?raw=true

(iPadユーザーでPlaygroundsアプリ使ってる方、
リンクから、直接iPadにPlaygroundプロジェクトをダウンロードできます。)

やったこと

UIVisualEffect のブラーのかかり具合を調節するメソッドやプロパティーは用意されてない。
でも、アニメーション用メソッドを使って無理やり?ブラーの調節ができる。

Animating Blur Radius

こちらの記事だと、スライダーの値(0-1)をアニメーションの経過タイミングに指定することで、ブラーのかかり具合を調節してる。

スライダーなしにブラーのかかり具合を調節したいので、単純に、

defineBlurRadius.swift
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の更新がされないとのこと。

てことで、回答にならって書いたら、ブラーの調整が反映された。

調節ができので、ブラーがかかってないところから任意のところまでブラーがかかるアニメーションを実装してみたのがこちら

animationBlurRadius.swift

// 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)

透明度を変更してアニメーションさせると、アニメーション中にかかってるブラーが消えるんじゃないかと思ったんだけど、消えてないように見える。

15
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
20