web-dev-qa-db-ja.com

UIVisualEffectViewおよび/またはUIBlurEffectをフェードインおよびフェードアウトする方法は?

UIBlurEffectでUIVisualEffectsViewをフェードインおよびフェードアウトしたい:

var blurEffectView = UIVisualEffectView()
blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))

UIButtonによって呼び出される関数内で通常のアニメーションを使用してフェードインします。フェードアウトと同じですが、.alpha = 0hidden = true

blurEffectView.hidden = false
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseOut) {
    self.blurEffectView.alpha = 1
}

これで、両方向のフェードは機能しますが、フェードするときにエラーが発生しますout

<UIVisualEffectView 0x7fdf5bcb6e80>は不透明度をアニメーション化するよう求められています。これにより、不透明度が1に戻るまで効果が壊れたように見えます。

質問

UIVisualEffectViewbreakingせずにフェードインおよびフェードトランジションなしで正常にフェードインするにはどうすればよいですか?

  • UIVisualEffectViewUIViewに入れて、それをフェードインしようとしましたが、成功しませんでした
86
LinusGeffarth

これはiOS9の新機能だと思いますが、アニメーションブロック内でUIVisualEffectViewの効果を設定できるようになりました。

let overlay = UIVisualEffectView()
// Put it somewhere, give it a frame...
UIView.animate(withDuration: 0.5) {
    overlay.effect = UIBlurEffect(style: .light)
}

削除するにはnilに設定します。

非常に重要-シミュレータでこれをテストするときは、これが機能するようにシミュレータのグラフィックス品質オーバーライドを高品質に設定してください。

179
jrturton

Appleドキュメント (現在)状態...

UIVisualEffectViewクラスを使用するときは、1未満のアルファ値を避けてください。

そして

視覚効果ビューまたはそのスーパービューでアルファを1未満に設定すると、多くの効果が正しく表示されないか、まったく表示されなくなります。

重要なコンテキストがここに欠けていると思います...

永続的なビューでは、1未満のアルファ値を避けることを目的とすることをお勧めします。私の謙虚な意見では、これはビューのアニメーションには適用されません。

私のポイント-アニメーションには1未満のアルファ値が許容されることをお勧めします。

端末メッセージの状態:

UIVisualEffectViewは、不透明度をアニメーション化するように求められています。これにより、不透明度が1に戻るまで効果が壊れたように見えます。

これを注意深く読むと、効果はが表示されますが壊れます。これに関する私のポイント:

  • 明らかな中断は、永続的なビューでのみ重要であり、変更されません。
  • アルファ値が1未満の永続的で不変のUIVisualEffectビューは、Appleが意図/設計したとおりには表示されません。そして
  • 端末内のメッセージはエラーではなく、単なる警告です。

上記の@jrturtonの答えを拡張して、問題を解決するのに役立てるために、私は追加します...

UIVisualEffectをフェードアウトするには、次の(Objective-C)コードを使用します。

UIView.animateWithDuration(1.0, animations: {
//  EITHER...
    self.blurEffectView.effect = UIBlurEffect(nil)
//  OR...
    self.blurEffectView.alpha = 0
}, completion: { (finished: Bool) -> Void in
    self.blurEffectView.removeFromSuperview()
} )

effectプロパティをnilに設定し、alphaプロパティを0に設定して、両方のメソッドを正常に使用します。

effectnilに設定すると、アニメーションの最後に「素敵なフラッシュ」(より良い説明が必要)が作成され、alpha0に設定することに注意してください。スムーズな移行を作成します。

(構文エラーを教えてください... obj-cで記述します。)

18
andrewbuilder

Swift 3を使用してiOS10と以前のバージョンの両方で動作するようになった解決策を次に示します。

extension UIVisualEffectView {

    func fadeInEffect(_ style:UIBlurEffectStyle = .light, withDuration duration: TimeInterval = 1.0) {
        if #available(iOS 10.0, *) {
            let animator = UIViewPropertyAnimator(duration: duration, curve: .easeIn) {
                self.effect = UIBlurEffect(style: style)
            }

            animator.startAnimation()
        }else {
            // Fallback on earlier versions
            UIView.animate(withDuration: duration) {
                self.effect = UIBlurEffect(style: style)
            }
        }
    }

    func fadeOutEffect(withDuration duration: TimeInterval = 1.0) {
        if #available(iOS 10.0, *) {
            let animator = UIViewPropertyAnimator(duration: duration, curve: .linear) {
                self.effect = nil
            }

            animator.startAnimation()
            animator.fractionComplete = 1
        }else {
            // Fallback on earlier versions
            UIView.animate(withDuration: duration) {
                self.effect = nil
            }
        }
    }

}

このGistをチェック を使用して、使用例を見つけることもできます。

13
Gunhan

回避策-UIVisualEffectViewをコンテナビューに配置し、そのコンテナのalphaプロパティを変更します。このアプローチは、iOS 9では完全に機能します。iOS10では機能しなくなったようです。

8
beryllium

基礎となる静的ビューのスナップショットを取得し、ぼかしビューの不透明度に触れることなくフェードインおよびフェードアウトできます。 blurViewのivarを想定:

func addBlur() {
    guard let blurEffectView = blurEffectView else { return }

    //snapShot = UIScreen.mainScreen().snapshotViewAfterScreenUpdates(false)
    let snapShot = self.view.snapshotViewAfterScreenUpdates(false)
    view.addSubview(blurEffectView)
    view.addSubview(snapShot)

    UIView.animateWithDuration(0.25, animations: {
        snapShot.alpha = 0.0
    }, completion: { (finished: Bool) -> Void in
        snapShot.removeFromSuperview()
    } )
}

func removeBlur() {
    guard let blurEffectView = blurEffectView else { return }

    let snapShot = self.view.snapshotViewAfterScreenUpdates(false)
    snapShot.alpha = 0.0
    view.addSubview(snapShot)

    UIView.animateWithDuration(0.25, animations: {
        snapShot.alpha = 1.0
    }, completion: { (finished: Bool) -> Void in
        blurEffectView.removeFromSuperview()
        snapShot.removeFromSuperview()
    } )
}
5
David H

コンソールの警告以外に、視覚効果ビューのアルファを問題なく変更できます。ビューは、ぼやけているのではなく、単に部分的に透明に見える場合があります。ただし、アニメーション中にアルファを変更するだけの場合、これは通常問題になりません。

アプリがクラッシュしたり、拒否されたりすることはありません。実際のデバイス(または8つ)でテストします。あなたがそれがどのように見えて実行するかに満足しているなら、それは大丈夫です。 Appleは、アルファ値が1の視覚効果ビューと同じように表示または実行できない可能性があることを警告しています。

5
Dave Batton

UIVisualEffectViewをフェードインする場合-iOS10の場合はUIViewPropertyAnimatorを使用します

    UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:nil];
    blurEffectView.frame = self.view.frame;
    blurEffectView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;

    UIView *blackUIView = [[UIView alloc]initWithFrame:self.view.frame];
    [bacgroundImageView addSubview:blackUIView];
    [blackUIView addSubview:blurEffectView];
    UIViewPropertyAnimator *animator  = [[UIViewPropertyAnimator alloc] initWithDuration:4.f curve:UIViewAnimationCurveLinear animations:^{
        [blurEffectView setEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleDark]];
    }];

その後、パーセントを設定できます

[animator setFractionComplete:percent];

iOS9では、アルファコンポーネントを使用できます

3
kiril kiroski

UIVisualEffectViewのアルファは常に1でなければなりません。背景色のアルファを設定することで効果を達成できると思います。

ソース: https://developer.Apple.com/library/ios/documentation/UIKit/Reference/UIVisualEffectView/index.html

2
Peter Lendvay

UIVisualEffectViewとコンテンツに別々のアニメーションを使用して、次のソリューションを作成しました。 viewWithTag()メソッドを使用して、UIView内のUIVisualEffectViewへの参照を取得しました。

let blurEffectView = UIVisualEffectView()
// Fade in
UIView.animateWithDuration(1) { self.blurEffectView.effect = UIBlurEffect(style: .Light) }    
UIView.animateWithDuration(1) { self.blurEffectView.viewWithTag(1)?.alpha = 1 }
// Fade out
UIView.animateWithDuration(1) { self.blurEffectView.effect = nil }    
UIView.animateWithDuration(1) { self.blurEffectView.viewWithTag(1)?.alpha = 0 }

私はアルファを変更する単一のアニメーションを好むでしょうが、これはエラーを回避し、同様に機能するようです。

1
demian

私はちょうどこの問題を抱えていて、それを回避する方法は、UIVisualEffectsViewをUIViewに格納し、そのUIViewのアルファをアニメーション化することでした。

これはうまく機能しましたが、アルファが1.0未満に変わるとすぐに白一色になり、非常に不快に見えました。これを回避するには、UIViewのレイヤープロパティcontainerView.layer.allowsGroupOpacity = falseを設定する必要があります。これにより、UIViewが白く点滅しなくなります。

これで、アルファプロパティを使用して、視覚効果ビューと他のサブビューを含むUIViewをアニメーション化/フェードアウトでき、グラフィカルな不具合や警告メッセージのログについて心配する必要がなくなりました。

1
user1898712

Alphaが0のuiviewを作成し、そのサブビューとしてblurviewを追加します。だから私はアニメーションでそれを非表示/表示または角を丸めることができます。

1

@ Tel4telおよび@cc応答を改善するために、パラメーターと簡単な説明を含む拡張機能を以下に示します。

extension UIView {

    // Perform a blur animation in the whole view
    // Effect tone can be .light, .dark, .regular...
    func blur(duration inSeconds: Double, effect tone: UIBlurEffectStyle) {
        let blurView = UIVisualEffectView(frame: self.bounds)
        self.addSubview(blurView)
        UIView.animate(withDuration: inSeconds) {
            blurView.effect = UIBlurEffect(style: tone)
        }
    }

    // Perform an unblur animation in the whole view
    func unblur(duration inSeconds: Double) {
        for childView in subviews {
            guard let effectView = childView as? UIVisualEffectView else { continue 
        }
            UIView.animate(withDuration: inSeconds, animations: {
                effectView.effect = nil
            }){
                didFinish in effectView.removeFromSuperview()
            }
        }
    }
}

その後、次のように使用できます:view.blur(duration: 5.0, effect: .light)またはview.unblur(duration: 3.0)

アニメーションをオーバーライドするため、viewDidLoad()で使用しないでください。また、シミュレータで実行する場合、アニメーションを表示できるようにグラフィックを高レベルに切り替えます([デバッグ]> [グラフィック品質のオーバーライド]> [高品質])。

0
Rafael Díaz
_visualEffectView.contentView.alpha = 0;

UIVisualEffectViewのアルファを変更するには、_visualEffectViewのcontentViewを変更する必要があります。_visualEffectViewのアルファを変更する場合、これを取得します

<UIVisualEffectView 0x7ff7bb54b490> is being asked to animate its opacity. This will cause the effect to appear broken until opacity returns to 1.
0
chile

通常、画面上にView Controllerを表示し、表示するView Controllerをぼかしたい場合にのみ、ぼかしをアニメーション化します。これを簡単にするために、blur()とunblur()をView Controllerに追加する拡張機能を次に示します。

extension UIViewController {

   func blur() {
       //   Blur out the current view
       let blurView = UIVisualEffectView(frame: self.view.frame)
       self.view.addSubview(blurView)
       UIView.animate(withDuration:0.25) {
           blurView.effect = UIBlurEffect(style: .light)
       }
   }

   func unblur() {
       for childView in view.subviews {
           guard let effectView = childView as? UIVisualEffectView else { continue }
           UIView.animate(withDuration: 0.25, animations: {
                effectView.effect = nil
           }) {
               didFinish in
               effectView.removeFromSuperview()
           }
       }
   }
}

もちろん、ユーザーがエフェクトスタイルを選択し、持続時間を変更し、アニメーションが完了したときに何かを呼び出し、blur()で追加されたビジュアルエフェクトビューにタグを付けて、ブラーを解除したときに削除される唯一のものになるようにすることで、これをより堅牢にすることができます( )などがありますが、これは「火災と忘却」タイプの操作である傾向があるため、これまでこれらのことを行う必要性が見つかりませんでした。

0
cc.

@ccの答えに基づいて、私は彼の拡張子を変更してビューをぼかします

 extension UIView {
 
 func blur(){
 //現在のビューをぼかします
 let blurView = UIVisualEffectView(frame:self.bounds )
 self.addSubview(blurView)
 UIView.animate(withDuration:0.25){
 blurView.effect = UIBlurEffect(style:.dark)
} 
} 
 
 func unblur(){
サブビューのchildViewの場合{
 guard let effectView = childView as? UIVisualEffectView else {継続} 
 UIView.animate(withDuration:2.5、animations:{
 effectView.effect = nil 
}){
 didFinish in 
 effectView.removeFromSuperview()
} 
} 
} 
} 
0
Tel4tel