MILLEN BOX

音楽好きの組み込みソフトエンジニアによるプログラミング(主にiOSアプリ開発)の勉強の記録

手軽にBlurViewが使えるSABlurImageViewを使ってみました [swift2.1] [SABlurImageView]

ものすごく久しぶりの投稿です。。。。
罪悪感でいっぱい。。。。

先日(と言っても随分前ですが、、、)iOS8で追加されたUIVisualEffectViewを使ってBlur効果を実現しました。

▶︎iOS8で追加されたUIVisualEffectViewを使ってBlur効果を作成する [UIVisualEffectView] [UIBlurEffect] - MILLEN BOX

しかしこの方法には問題があります。iOS端末の設定によってはBlurEffectがかかりません。以下記事参照。

▶︎UIVisualEffectViewを使ったblur効果が環境によって動かないぞ?と思ったら [UIVisualEffectView] [UIBlurEffect] - MILLEN BOX

そこで今回はiOS端末の設定に依存しないBlurRffectの掛け方をシェアしようと思います。

f:id:anthrgrnwrld:20160202204238g:plain

今回作成したプロジェクトのGitHubは以下です。

▶︎GitHub - anthrgrnwrld/saBlurEffect

どうやって実現する?

さてBlurEffectの実現方法ですが、実は先人の方々が既に作ってくれているのです。
その中で今回は、オープンソースとして公開されているSABlurImageViewというクラスを使用したいと思います。

▶︎GitHub - marty-suzuki/SABlurImageView: You can use blur effect and it's animation easily to call only two methods.

以下のQiitaにも記事がありました。

▶︎iOSアプリ開発でブラーエフェクトを手間なく使う方法 - Qiita

このクラスを使ったサンプルも上記リンクにはあったのですが、方法がちょっと私がしたい使い方ではありませんでした。
サンプルの方法だとUIImageView全体にBlurEffectをかけるようなイメージで書かれていました。
しかし、私はこれのように、UIImageViewの特定部分のみEffectをかけるような形で使用したかったのです。

そこで「特定部分のみEffectをかける」ということを実現するために、UIImageやUIViewから特定部分をUIImageとして切り出す方法を学び、以下の記事達を書きました。

▶︎UIImageの一部を切り取る方法 [swift2.1] - MILLEN BOX

▶︎UIViewの一部をUIImageとして切り取る方法 [swift2.1] [Context] [CGAffineTransform] - MILLEN BOX

そして今日、晴れて(やっと)SABlurImageViewのオレオレな使い方を公開する運びとなりました。

SABlurImageViewを使用する準備

SABlurImageView をダウンロードします。
ダウンロード後生成された"SABlurImageView"フォルダ直下にある"SABlurImageView"フォルダ(同じ名前だから注意)を、自分のプロジェクトにガツンと放り込みます。
これで使用準備は完了です。

f:id:anthrgrnwrld:20160202075931p:plain
※ testSABlurImageViewが今回私が作成したプロジェクト名、そしてSABlurImageViewフォルダが上記手順にて追加したものです。

ちなみにCocoaPodsでもSABlurImageViewは使用出来ますが、私の宗教上の理由により今回は上記方法にて利用しています。(単に覚えるのが面倒くさいだけ。。。)

SABlurImageViewの使用方法

単にUIImage全体にBlurEffectをかけるだけであれば、引数にUIImageを渡してあげてSABlurViewをインスタンス化し、addSubViewすれば行けます。

effectView = SABlurImageView(image: effectImage)
effectView.addBlurEffect(25, times: 2)    //Blur度合とかける回数を指定
self.addSubView(effectView)

しかし今回私は「渡したUIImage」の「特定範囲にのみ」Effectをかけたかった...ということで、以下の addVirtualEffectView という関数を作成しました。
ポイントはev.frame = frameRectにてblurをかける大きさを指定しているところでしょうか。
(追記)またeffectViewについてはViewControllerのプロパティとして private var effectView : SABlurImageView? //Effect用View という形で予め宣言済みです。(Github参照)

    /**
     エフェクトを適用する
     
     - parameter view:blurをかける対象のView
     - parameter rect:blurをかける位置とサイズ(CGRect)
     - parameter blurLevel:blurレベル
    */
    func addVirtualEffectView(view :UIView?, rect :CGRect?, blurLevel :SABlurEffectStyle?) {
        //print("\(__FUNCTION__) is called!")
        
        //effectViewの内容を一旦初期化する
        initEffectView()
        
        guard let blrlv = blurLevel else {
            return
        }
        
        guard let targetView = view else {
            return
        }
        
        guard let frameRect = rect else {
            return
        }
        
        //blurをかけたい部分をUIImageとして取り出す(=effectImage)
        let effectImage = clipView(view, rect: frameRect)

        
        //blurをかけたい部分(=effectImage)をBlur生成用関数(=SABlurImageView)にセットする
        effectView = SABlurImageView(image: effectImage)
        
        guard let ev = effectView else {
            print("\(__LINE__) \(__FUNCTION__) is called!")
            return
        }

        //Blurの大きさ,座標,形を指定する
        ev.frame = frameRect
        ev.layer.masksToBounds = true
        ev.layer.cornerRadius = 20.0
        
        //blurのかけ具合を指定する
        switch blrlv {
        case .Weak:
            ev.addBlurEffect(25, times: 2)
        case .Default:
            ev.addBlurEffect(50, times: 2)
        case .Strong:
            ev.addBlurEffect(100, times: 3)
        }
        
        //blurがかかったViewを追加する
        targetView.addSubview(ev)
        
    }

あとはこれとかこれとかこれとかでやったことのおさらいで実装の意味は理解できると思います。
更新、ちょっと空くと億劫になるのと、文章の書き方忘れてしまいますね。。。
もっとサクッと更新できるようにしていきたいです。