कैसे एक UIVisualEffectView और / या UIBlurEffect को अंदर और बाहर फीका करें?


92

मैं एक 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
}

अब, दोनों दिशाओं में लुप्त हो जाना काम करता है लेकिन यह मुझे एक त्रुटि देता है जब लुप्त होती है :

<UIVisualEffectView 0x7fdf5bcb6e80>इसकी अपारदर्शिता को चेतन करने के लिए कहा जा रहा है। यह प्रभाव दिखाई देगा जब तक कि अस्पष्टता 1 तक वापस आ जाए।

सवाल

कैसे मैं इसे तोड़ने और एक लुप्त होती संक्रमण के UIVisualEffectViewबिना अंदर और बाहर सफलतापूर्वक फीका ?

ध्यान दें

  • मैंने UIVisualEffectViewएक में डालने की कोशिश की UIViewऔर उस एक को फीका कर दिया , कोई सफलता नहीं मिली

आप निम्न से त्रुटि से बच सकते हैं: 1. ब्लरफेक्ट को प्रारंभिक शैली निर्दिष्ट नहीं करना। यानी, var blurEffectView = UIVisualEffectView () और फिर 2. blEffect को blurEffectView को एनीमेशन ब्लॉक में असाइन करना। 3. "ब्लिफ़ेक्ट ऑफ़ ब्लोएफ़ेक्टव्यू" के असाइनमेंट को एनिमेट करने के लिए एडजस्टमेंट की जगह ब्लुफेफ़ेक्ट व्यू.आलफा को किया जाता है। ** त्रुटि तब भी दिखाई देगी जब आप एक प्रारंभिक मान निर्दिष्ट करते हैं, इसे शून्य करते हैं, फिर इसे वापस जोड़ते हैं। तो त्रुटि को रोकने की कुंजी एनीमेशन ब्लॉक तक ब्लीफेक्ट व्यू के प्रभाव को असाइन नहीं करना है।
ऑब्जेक्टिवटीसी

यह भी उल्लेख करने की आवश्यकता है, त्रुटि से बचने के लिए blurEffectView में अल्फा = 1.0 होना चाहिए। किसी भी तरह से अल्फा के साथ छेड़छाड़ त्रुटि पैदा करेगा। उदाहरण के लिए, एनीमेशन ब्लॉक से पहले आप blurEffectView.alpha = 0.7 सेट करते हैं, फिर एनीमेशनब्लॉक में आप blurEffectView.effect = blurEffect असाइन करते हैं, त्रुटि उत्पन्न होती है।
ऑब्जेक्टिव

जवाबों:


185

मुझे लगता है कि यह iOS9 में नया है, लेकिन अब आप UIVisualEffectViewएक एनीमेशन ब्लॉक के अंदर के प्रभाव को सेट कर सकते हैं :

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

इसे nilनिकालने के लिए सेट करें ।

बहुत महत्वपूर्ण - सिम्युलेटर पर यह परीक्षण करते समय, अपने सिम्युलेटर ग्राफिक्स गुणवत्ता ओवरराइड को उच्च गुणवत्ता के लिए सेट करें ताकि यह काम कर सके।


1
अच्छी तरह से काम। धन्यवाद।
बाजा207

महान! जैसा कि आपने कहा, iOS 8 के लिए हालांकि काम नहीं करता है: /
LinusGeffarth

ठीक वैसा ही क्योंकि मैंने ऊपर जो लिखा है। मैंने इसे अब मंजूरी दे दी है। @ जप्रोस
लिनसग्राफर्थ

10
तुम भी एक सुंदर "कलंक" पाने के लिए शून्य करने के लिए प्रभाव सेट कर सकते हैं
jpros

1
@jpros क्या आप समझाते हैं कि "ब्लर आउट" से आपका क्या मतलब होगा?
ndmeiri

19

एप्पल प्रलेखन (वर्तमान में) में कहा गया है ...

UIVisualEffectView वर्ग का उपयोग करते समय, उन अल्फा मानों से बचें जो 1 से कम हैं।

तथा

विज़ुअल इफ़ेक्ट व्यू या इसके किसी भी सुपरवाइज़ पर अल्फा को 1 से कम पर सेट करने से कई प्रभाव गलत दिखते हैं या बिल्कुल दिखाई नहीं देते हैं।

मेरा मानना ​​है कि कुछ महत्वपूर्ण संदर्भ यहां गायब है ...

मेरा सुझाव है कि आशय उन अल्फा मूल्यों से बचना है जो लगातार देखने के लिए 1 से कम हैं। मेरी विनम्र राय में यह एक दृश्य के एनीमेशन पर लागू नहीं होता है।

मेरी बात - मेरा सुझाव है कि 1 से कम अल्फा मान एनिमेशन के लिए स्वीकार्य हैं।

टर्मिनल संदेश बताता है:

UIVisualEffectView को इसकी अपारदर्शिता को चेतन करने के लिए कहा जा रहा है। यह प्रभाव दिखाई देगा जब तक कि अस्पष्टता 1 तक वापस आ जाए।

इसे ध्यान से पढ़ने पर असर टूटता हुआ दिखाई देगा । इस पर मेरे अंक:

  • स्पष्ट विराम केवल एक दृश्य के लिए वास्तव में मायने रखता है जो लगातार है - नहीं बदल रहा है;
  • UIVisualEffect1 से कम अल्फा मान के साथ एक निरंतर / अपरिवर्तनीय दृश्य Apple द्वारा प्रस्तुत / डिज़ाइन नहीं किया जाएगा; तथा
  • टर्मिनल में संदेश केवल एक चेतावनी नहीं है।

ऊपर @ jrturton के उत्तर का विस्तार करने से मुझे अपनी समस्या हल करने में मदद मिली, मैं जोड़ूंगा ...

UIVisualEffectनिम्नलिखित (उद्देश्य-सी) कोड के उपयोग को फीका करने के लिए:

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 में लिखता हूं।)


आपके योगदान के लिए धन्यवाद। मुझे आपका बिंदु पता है; त्रुटि मेरे लिए पहले से ही w / ठीक-ठीक बताई गई है जिसका आपने हल किया है :)
LinusGeffarth

14

यहाँ समाधान है कि मैंने समाप्त किया जो कि iOS10 और पिछले संस्करणों दोनों पर काम करता है स्विफ्ट 3 का उपयोग कर रहा है

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
            }
        }
    }

}

उदाहरण का उपयोग करने के लिए आप इस जिस्ट को भी देख सकते हैं ।


UIViewPropertyAnimatorआईओएस 11 में काम करने वाली एकमात्र चीज का उपयोग करना इसके लिए धन्यवाद!
लाइनसग्राफर

जोड़ना न भूलें: आयात UIKit
ओलेकेंडर

8

बस एक समाधान - UIVisualEffectViewएक कंटेनर दृश्य में डालें और alphaउस कंटेनर के लिए संपत्ति बदलें । यह दृष्टिकोण iOS 9 पर मेरे लिए पूरी तरह से काम करता है। ऐसा लगता है कि यह अब iOS 10 में काम नहीं करता है।


ठंडा। धन्यवाद, कोशिश करेंगे कि :)
LinusGeffarth

1
क्या आप नमूना कोड प्रदान कर सकते हैं। यह काम नहीं लगता है।
cnotethegr8

आईओएस 9 में मेरे लिए काम करता है
मेप

@DerrickHunt यहाँ। क्या आपको एक समाधान मिला?
डेमस्टीरुथे सीपी

2
@damirstuhec यदि आपकी परियोजना केवल iOS 10 है, तो आप UIBlurView ताकत को एनिमेट करने के लिए नए UIViewPropertyAnimator क्लास का उपयोग कर सकते हैं। यदि आपको पुराने संस्करणों का समर्थन करने की आवश्यकता है, तो आप उपरोक्त कोड का उपयोग कर सकते हैं और #available कीवर्ड का उपयोग कर UIViewPropertyAnimator का उपयोग कर सकते हैं।
डेरिक हंट

5

आप कंसोल में चेतावनी के अलावा किसी भी समस्या के बिना दृश्य प्रभाव दृश्य के अल्फा को बदल सकते हैं। यह दृश्य धुंधला होने के बजाय केवल आंशिक रूप से पारदर्शी दिखाई दे सकता है। लेकिन यह आमतौर पर एक समस्या नहीं है यदि आप एनीमेशन के दौरान केवल अल्फा बदल रहे हैं।

आपका ऐप क्रैश नहीं हो रहा है या इसके लिए अस्वीकृत नहीं है। इसे वास्तविक डिवाइस (या आठ) पर टेस्ट करें। यदि आप खुश हैं कि यह कैसे दिखता है और प्रदर्शन करता है, तो यह ठीक है। ऐप्पल ने आपको केवल चेतावनी दी है कि यह 1 के अल्फा मान के साथ एक दृश्य प्रभाव दृश्य को नहीं देख सकता है या प्रदर्शन नहीं कर सकता है।


5

आप स्थैतिक अंतर्निहित दृश्य का एक स्नैपशॉट ले सकते हैं, और इसे धब्बा दृश्य की अस्पष्टता को छुए बिना अंदर और बाहर फीका कर सकते हैं। ब्लर व्यू का आइवर मान लेना:

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()
    } )
}

साथ ही अच्छा विचार है, लेकिन यह धब्बा दृश्य के नीचे गैर-स्थिर (चलती / एनिमेटेड) सामग्री के लिए अच्छी तरह से काम नहीं करेगा।
19us में LinusGeffarth

@LinusG। खैर, Apple का कहना है कि ब्लर व्यू अल्फा के साथ नहीं खेलना चाहिए। आप अपने आधार दृश्य के स्क्रीन शॉट्स को हथियाने के लिए कैडिसप्लेलिंक का उपयोग कर सकते हैं, फिर उन्हें एक छवि दृश्य में प्रस्तुत कर सकते हैं (शायद आपने जो किया था - वास्तविक हल्का) - और शीर्ष दृश्य में उन लोगों को दिखाते हैं जो इसकी अपारदर्शिता को 0. में बदल सकते हैं, लेकिन बहुत संभव है काम।
डेविड एच।

1
यह एकमात्र तरीका था (अब तक) मैं iOS 10 में जो कुछ भी हासिल करना चाहता था उसे हासिल करने में सक्षम रहा हूं - एक बहुत ही डार्क ब्लर इफेक्ट के साथ फुलस्क्रीन पर एक मोडल में फीका। धन्यवाद!
ग्राहम

3

आप में आप को फीका करना चाहते हैं 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 के लिए आप अल्फा घटक का उपयोग कर सकते हैं


2
प्रश्न को विशेष रूप से "स्विफ्ट" टैग किया गया है, न कि "उद्देश्य-सी": कृपया स्विफ्ट में एक उत्तर प्रदान करें। धन्यवाद!
एरिक आया

1
उद्देश्य सी कोड के लिए धन्यवाद। मुझे यह आसान लगता है क्योंकि सूचीबद्ध कई अन्य उदाहरण नहीं थे।
एडम वेयर

2

UIVisualEffectView का अल्फ़ा हमेशा 1. होना चाहिए। मुझे लगता है कि आप बैकग्राउंड कलर के अल्फ़ाज़ सेट करके इफ़ेक्ट हासिल कर सकते हैं।

स्रोत: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIVisualEffectView/index.html


पीटर, क्या आप कृपया यह बता सकते हैं कि पृष्ठभूमि रंग का अल्फा कैसे सेट किया जाए?
बोरिस वाई।

@bor मिसाल colorWithAlphaComponent:पर विधि का उपयोग करें UIColor। हालांकि पृष्ठभूमि के रंग को स्थापित करने के साथ एक ही प्रभाव को कैसे प्राप्त किया जाए, यह सुनिश्चित नहीं है।
नेमसिस

पृष्ठभूमि को बदलकर अल्फा घटक अपेक्षित रूप से काम नहीं कर रहा है
हांगहो झांग

1

मैं एक uiview बनाता हूं जो अल्फा 0 है और उस के सबव्यू के रूप में ब्लरव्यू जोड़ते हैं। तो मैं इसे एनीमेशन के साथ कोनों को छिपा / दिखा या गोल कर सकता हूं।


1

मैं निम्नलिखित समाधान के साथ UIVisualEffectViewऔर सामग्री के लिए अलग एनिमेशन का उपयोग कर समाप्त हुआ । मैं अंदर के viewWithTag()लिए एक संदर्भ प्राप्त करने के लिए विधि का इस्तेमाल किया ।UIViewUIVisualEffectView

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

मुझे बस यह समस्या थी और जिस तरह से मैंने इसके चारों ओर पाया वह UIVisualEffectsView को एक UIView, और UIView के अल्फ़ा को चेतन करने के लिए था।

यह अच्छी तरह से काम करता है, सिवाय इसके कि जैसे ही अल्फा 1.0 से नीचे बदल गया यह एक ठोस सफेद में बदल गया और बहुत परेशान लग रहा था। इसके आस-पास जाने के लिए, आपको UIView की परत संपत्ति सेट करनी होगीcontainerView.layer.allowsGroupOpacity = false और यह इसे सफेद होने से रोकेगा।

अब आप UIView को विज़ुअल इफेक्ट्स व्यू से युक्त / फीका कर सकते हैं और इसे अल्फा प्रॉपर्टी का उपयोग करके किसी अन्य सबव्यू में शामिल कर सकते हैं और किसी भी ग्राफिकल ग्लिच के बारे में चिंता करने की ज़रूरत नहीं है या यह चेतावनी संदेश लॉग कर रहा है।


0
_visualEffectView.contentView.alpha = 0;

UIVisualEffectView के अल्फा को बदलने के लिए, आपको _visualEffectView के कंटेंटव्यू को बदलना चाहिए। यदि आप _visualEffectView के अल्फा को बदलते हैं, तो आपको यह मिल जाएगा

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

0

आमतौर पर, मैं केवल एक धब्बा को चेतन करना चाहता हूं जब मैं स्क्रीन पर एक दृश्य नियंत्रक पेश कर रहा हूं और प्रस्तुत दृश्य नियंत्रक को धुंधला करना चाहता हूं। यहाँ एक एक्सटेंशन है जो धुंधला () और अनब्लूर () को एक व्यू कंट्रोलर से जोड़ता है ताकि उसकी सुविधा मिल सके:

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()
           }
       }
   }
}

आप निश्चित रूप से उपयोगकर्ता को प्रभाव शैली का चयन करने की अनुमति देकर इसे और अधिक मजबूत बना सकते हैं, अवधि को संशोधित कर सकते हैं, एनीमेशन पूरा होने पर कुछ कॉल कर सकते हैं, कलंक में जोड़े गए दृश्य प्रभाव दृश्य को टैग कर सकते हैं (यह सुनिश्चित करने के लिए कि यह केवल एक हटा दिया गया है जब आप अस्पष्ट हों ( ), आदि, लेकिन मुझे अब तक इन चीजों को करने की आवश्यकता नहीं है, क्योंकि यह "आग और भूल" प्रकार का ऑपरेशन है।


"आग और भूल" इतनी भरोसेमंद है! हा
लिनुसेफर्थ

0

@ cc के उत्तर के आधार पर मैंने एक दृश्य को धुंधला करने के लिए उसके विस्तार को संशोधित किया

विस्तार UIView {

    फंक ब्लर () {
        // वर्तमान दृश्य को धुंधला करें
        धुंधला होने दें = UIVisualEffectView (फ्रेम: स्व.बाउंड)
        self.addSubview (blurView)
        UIView.animate (अवधि: 0.25) {
            blurView.effect = UIBlurEffect (शैली:। डार्क)
        }
    }

    कवक unblur () {
        उप-साक्षात्कार में चाइल्डव्यू के लिए {
            गार्ड let effectView = childView के रूप में? UIVisualEffectView {{जारी रखें}
            UIView.animate (WithDuration: 2.5, एनिमेशन: {
                effectView.effect = नील
            } {
                में किया
                effectView.removeFromSuperview ()
            }
        }
    }
}

0

@ 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()क्योंकि यह एनीमेशन को ओवरराइड करेगा। इसके अलावा, जब कोई सिम्युलेटर पर चल रहा है, तो एनिमेशन को देखने के लिए ग्राफिक्स को उच्च स्तर पर ले जाएं (डेब्यू> ग्राफिक्स गुणवत्ता ओवरराइड> उच्च गुणवत्ता)।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.