94

UIBlurEffect を使用して UIVisualEffectsView をフェードアウトしたい:

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

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

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

現在、両方向のフェードは機能しますが、フェードアウト時にエラーが発生ます。

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

質問

UIVisualEffectViewフェード インとフェード アウトを中断せずフェード トランジションを行うにはどうすればよいですか?

ノート

  • を入れてフェードしようとしましたがUIVisualEffectViewUIView成功しませんでした
4

15 に答える 15

19

Appleのドキュメント(現在)には次のように記載されています...

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

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

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

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

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

端末メッセージには次のように記載されています。

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

これを注意深く読むと、効果が壊れているように見えます。これに関する私のポイント:

  • 明らかな中断は、永続的であり、変更されていないビューにとってのみ重要です。
  • UIVisualEffectアルファ値が 1 未満の持続的 / 不変のビューは、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に設定します。alpha0

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

(構文エラーがあれば教えてください... obj-c で書きます。)

于 2016-03-26T00:45:13.077 に答える
5

下にある静的なビューのスナップショットを取り、ぼかしビューの不透明度に触れることなくフェードインおよびフェードアウトすることができます。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()
    } )
}
于 2015-07-29T18:45:57.010 に答える
5

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

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

于 2015-05-13T17:45:41.693 に答える
1

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 }

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

于 2015-11-06T02:13:39.357 に答える
1

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

于 2015-12-02T07:38:43.713 に答える
0

通常、ビュー コントローラーを画面上に表示し、表示中のビュー コントローラーをぼかしたい場合にのみ、ぼかしをアニメーション化します。これを容易にするために、blur() と unblur() をビュー コントローラに追加する拡張機能を次に示します。

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() でタグ付けして、 unblur( )などですが、これは「ファイアアンドフォーゲット」タイプの操作になる傾向があるため、これまでのところこれらのことを行う必要があるとは思いませんでした。

于 2017-05-30T18:44:15.313 に答える
0

@ccの回答に基づいて、ビューをぼかすために彼の拡張機能を変更しました

拡張 UIView {

    関数ぼかし() {
        // 現在のビューをぼかす
        let blurView = UIVisualEffectView(frame: self.bounds)
        self.addSubview(blurView)
        UIView.animate(withDuration:0.25) {
            blurView.effect = UIBlurEffect(スタイル: .dark)
        }
    }

    関数 unblur() {
        サブビューの childView の場合 {
            guard let effectView = childView as? UIVisualEffectView その他 { 続行 }
            UIView.animate(withDuration: 2.5、アニメーション: {
                effectView.effect = なし
            }) {
                で終わった
                effectView.removeFromSuperview()
            }
        }
    }
}
于 2018-08-30T12:45:39.140 に答える