UIBlurEffectでUIVisualEffectsViewをフェードインおよびフェードアウトしたい:
var blurEffectView = UIVisualEffectView()
blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
UIButton
によって呼び出される関数内で通常のアニメーションを使用してフェードインします。フェードアウトと同じですが、.alpha = 0
&hidden = true
:
blurEffectView.hidden = false
UIView.animate(withDuration: 1, delay: 0, options: .curveEaseOut) {
self.blurEffectView.alpha = 1
}
これで、両方向のフェードは機能しますが、フェードするときにエラーが発生しますout:
<UIVisualEffectView 0x7fdf5bcb6e80>
は不透明度をアニメーション化するよう求められています。これにより、不透明度が1に戻るまで効果が壊れたように見えます。
質問
UIVisualEffectView
をbreakingせずにフェードインおよびフェードトランジションなしで正常にフェードインするにはどうすればよいですか?
注
UIVisualEffectView
をUIView
に入れて、それをフェードインしようとしましたが、成功しませんでしたこれはiOS9の新機能だと思いますが、アニメーションブロック内でUIVisualEffectView
の効果を設定できるようになりました。
let overlay = UIVisualEffectView()
// Put it somewhere, give it a frame...
UIView.animate(withDuration: 0.5) {
overlay.effect = UIBlurEffect(style: .light)
}
削除するにはnil
に設定します。
非常に重要-シミュレータでこれをテストするときは、これが機能するようにシミュレータのグラフィックス品質オーバーライドを高品質に設定してください。
Appleドキュメント (現在)状態...
UIVisualEffectViewクラスを使用するときは、1未満のアルファ値を避けてください。
そして
視覚効果ビューまたはそのスーパービューでアルファを1未満に設定すると、多くの効果が正しく表示されないか、まったく表示されなくなります。
重要なコンテキストがここに欠けていると思います...
永続的なビューでは、1未満のアルファ値を避けることを目的とすることをお勧めします。私の謙虚な意見では、これはビューのアニメーションには適用されません。
私のポイント-アニメーションには1未満のアルファ値が許容されることをお勧めします。
端末メッセージの状態:
UIVisualEffectViewは、不透明度をアニメーション化するように求められています。これにより、不透明度が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
に設定して、両方のメソッドを正常に使用します。
effect
をnil
に設定すると、アニメーションの最後に「素敵なフラッシュ」(より良い説明が必要)が作成され、alpha
を0
に設定することに注意してください。スムーズな移行を作成します。
(構文エラーを教えてください... obj-cで記述します。)
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をチェック を使用して、使用例を見つけることもできます。
回避策-UIVisualEffectView
をコンテナビューに配置し、そのコンテナのalpha
プロパティを変更します。このアプローチは、iOS 9では完全に機能します。iOS10では機能しなくなったようです。
基礎となる静的ビューのスナップショットを取得し、ぼかしビューの不透明度に触れることなくフェードインおよびフェードアウトできます。 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()
} )
}
コンソールの警告以外に、視覚効果ビューのアルファを問題なく変更できます。ビューは、ぼやけているのではなく、単に部分的に透明に見える場合があります。ただし、アニメーション中にアルファを変更するだけの場合、これは通常問題になりません。
アプリがクラッシュしたり、拒否されたりすることはありません。実際のデバイス(または8つ)でテストします。あなたがそれがどのように見えて実行するかに満足しているなら、それは大丈夫です。 Appleは、アルファ値が1の視覚効果ビューと同じように表示または実行できない可能性があることを警告しています。
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では、アルファコンポーネントを使用できます
UIVisualEffectViewのアルファは常に1でなければなりません。背景色のアルファを設定することで効果を達成できると思います。
ソース: https://developer.Apple.com/library/ios/documentation/UIKit/Reference/UIVisualEffectView/index.html
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 }
私はアルファを変更する単一のアニメーションを好むでしょうが、これはエラーを回避し、同様に機能するようです。
私はちょうどこの問題を抱えていて、それを回避する方法は、UIVisualEffectsViewをUIViewに格納し、そのUIViewのアルファをアニメーション化することでした。
これはうまく機能しましたが、アルファが1.0未満に変わるとすぐに白一色になり、非常に不快に見えました。これを回避するには、UIViewのレイヤープロパティcontainerView.layer.allowsGroupOpacity = false
を設定する必要があります。これにより、UIViewが白く点滅しなくなります。
これで、アルファプロパティを使用して、視覚効果ビューと他のサブビューを含むUIViewをアニメーション化/フェードアウトでき、グラフィカルな不具合や警告メッセージのログについて心配する必要がなくなりました。
Alphaが0のuiviewを作成し、そのサブビューとしてblurviewを追加します。だから私はアニメーションでそれを非表示/表示または角を丸めることができます。
@ 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()
で使用しないでください。また、シミュレータで実行する場合、アニメーションを表示できるようにグラフィックを高レベルに切り替えます([デバッグ]> [グラフィック品質のオーバーライド]> [高品質])。
_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.
通常、画面上に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()で追加されたビジュアルエフェクトビューにタグを付けて、ブラーを解除したときに削除される唯一のものになるようにすることで、これをより堅牢にすることができます( )などがありますが、これは「火災と忘却」タイプの操作である傾向があるため、これまでこれらのことを行う必要性が見つかりませんでした。
@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() } } } }