स्विफ्ट में एनीमेशन में एक साधारण फीका बनाओ?


82

मैं स्विफ्ट में एक साधारण एनीमेशन बनाने की कोशिश कर रहा हूं। यह एक फीका है।

मैंने प्रयास किया:

self.myFirstLabel.alpha = 0
self.myFirstButton.alpha = 0
self.mySecondButton.alpha = 0

फिर मेरे पास है:

self.view.addSubview(myFirstLabel)
self.view.addSubview(myFirstButton)
self.view.addSubview(mySecondButton)

और तब:

UIView.animateWithDuration(1.5, animations: {
 self.myFirstLabel.alpha = 1.0
 self.myFirstButton.alpha = 1.0
 self.mySecondButton.alpha = 1.0
})

मेरे पास यह सब मेरे viewDidLoad फ़ंक्शन में है।

मैं यह काम कैसे पूरा कर सकता हूं?


सभी तत्व एक ही समय में आते हैं। जब दृश्य लोड होता है।
बेनर Ben३

क्या आप सुनिश्चित हैं कि दृश्य ठीक से xib में झुके हुए हैं?
२०:१० पर २१

मैं आईबी का उपयोग नहीं कर रहा हूं। सब कुछ प्रोग्राम है।
बेनर .३

आपके द्वारा दिए गए कोड से, सब कुछ काम करना चाहिए (और इसका स्विफ्ट से कोई लेना-देना नहीं है)। कहीं और त्रुटि होनी चाहिए।
आकर्षित

दृश्य उपस्थिति पद्धति को कॉल करने पर विचार करें viewWillAppearया viewDidAppearजैसा कि आप नहीं जानते कि लोड होने और प्रदर्शित होने के बीच क्या होता है।
ए-लाइव

जवाबों:


121

समस्या यह है कि आप व्यू कंट्रोलर के जीवनचक्र में बहुत जल्दी एनीमेशन शुरू करने की कोशिश कर रहे हैं। मेंviewDidLoad , दृश्य अभी बनाया गया है, और अभी तक दृश्य पदानुक्रम में जोड़ा नहीं गया है, इसलिए subviewsइस बिंदु पर इसके किसी एक को चेतन करने का प्रयास बुरे परिणाम पैदा करता है।

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

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    UIView.animate(withDuration: 1.5) {
        self.myFirstLabel.alpha = 1.0
        self.myFirstButton.alpha = 1.0
        self.mySecondButton.alpha = 1.0
    }
}

क्या इसके लिए viewWillAppearअधिक उपयुक्त है?
टन

1
याद रखें, यदि आपके पास केवल 1 स्टेटमेंट है, तो आपको एक रिटर्न जोड़ने की जरूरत हैUIView.animateWithDuration(1.5, animations: { self.myFirstLabel.alpha = 1.0 return })
ओशेवन्स

@oshevans क्या आप क्लोजर के अंत में रिटर्न स्टेटमेंट जोड़ने की आवश्यकता का उल्लेख कर रहे हैं? यह ज्यादातर नवीनतम Xcode संस्करणों में तय किया गया है।
मिक मैकलम

मेरे पास एक समान त्रुटि है। कृपया देखें कि क्या आप मेरी मदद कर सकते हैं: stackoverflow.com/questions/29910669/…
Teo Inke

@ 0x7fffffff '... ज्यादातर निश्चित ...' - यह आशाजनक आवाज नहीं है; / फिर भी 6.2 से अपडेट करने के लिए
ओशिवैन

46

0x7ffffff का उत्तर ठीक है और निश्चित रूप से संपूर्ण है।

एक प्लस के रूप में, मैं आपको इस तरह से एक यूआईईवीवाई विस्तार करने का सुझाव देता हूं:

public extension UIView {

  /**
  Fade in a view with a duration

  - parameter duration: custom animation duration
  */
  func fadeIn(duration duration: NSTimeInterval = 1.0) {
    UIView.animateWithDuration(duration, animations: {
        self.alpha = 1.0
    })
  }

  /**
  Fade out a view with a duration

  - parameter duration: custom animation duration
  */
  func fadeOut(duration duration: NSTimeInterval = 1.0) {
    UIView.animateWithDuration(duration, animations: {
        self.alpha = 0.0
    })
  }

}

स्विफ्ट -3

/// Fade in a view with a duration
/// 
/// Parameter duration: custom animation duration
func fadeIn(withDuration duration: TimeInterval = 1.0) {
    UIView.animate(withDuration: duration, animations: {
        self.alpha = 1.0
    })
}

/// Fade out a view with a duration
///
/// - Parameter duration: custom animation duration
func fadeOut(withDuration duration: TimeInterval = 1.0) {
    UIView.animate(withDuration: duration, animations: {
        self.alpha = 0.0
    })
}

इस तरह आप अपने कोड में यह कर सकते हैं:

let newImage = UIImage(named: "")
newImage.alpha = 0 // or newImage.fadeOut(duration: 0.0)
self.view.addSubview(newImage)
... 
newImage.fadeIn()

कोड का पुन: उपयोग महत्वपूर्ण है!


7

केवल समाधान स्विफ्ट

लुका के एवर के समान , मैं एक UIViewएक्सटेंशन का उपयोग करता हूं । उनके समाधान की तुलना में, मैं DispatchQueue.main.asyncयह सुनिश्चित करने के लिए उपयोग करता हूं कि एनिमेशन मुख्य धागे पर किए गए हैं, alphaएक विशिष्ट मूल्य के लिए फ़ेडिंग और durationक्लीनर कोड के लिए वैकल्पिक पैरामीटर।

extension UIView {
  func fadeTo(_ alpha: CGFloat, duration: TimeInterval = 0.3) {
    DispatchQueue.main.async {
      UIView.animate(withDuration: duration) {
        self.alpha = alpha
      }
    }
  }

  func fadeIn(_ duration: TimeInterval = 0.3) {
    fadeTo(1.0, duration: duration)
  }

  func fadeOut(_ duration: TimeInterval = 0.3) {
    fadeTo(0.0, duration: duration)
  }
}

इसका इस्तेमाल कैसे करें:

// fadeIn() - always animates to alpha = 1.0
yourView.fadeIn()     // uses default duration of 0.3
yourView.fadeIn(1.0)  // uses custom duration (1.0 in this example)

// fadeOut() - always animates to alpha = 0.0
yourView.fadeOut()    // uses default duration of 0.3
yourView.fadeOut(1.0) // uses custom duration (1.0 in this example)

// fadeTo() - used if you want a custom alpha value
yourView.fadeTo(0.5)  // uses default duration of 0.3
yourView.fadeTo(0.5, duration: 1.0)

5

यदि आप दोहराए जाने वाले फीका एनीमेशन चाहते हैं, तो आप CABasicAnimationनीचे दिए गए उपयोग करके ऐसा कर सकते हैं :

पहले UIView एक्सटेंशन बनाएं:

extension UIView {

    enum AnimationKeyPath: String {
        case opacity = "opacity"
    }

    func flash(animation: AnimationKeyPath ,withDuration duration: TimeInterval = 0.5, repeatCount: Float = 5){
        let flash = CABasicAnimation(keyPath: animation.rawValue)
        flash.duration = duration
        flash.fromValue = 1 // alpha
        flash.toValue = 0 // alpha
        flash.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        flash.autoreverses = true
        flash.repeatCount = repeatCount

        layer.add(flash, forKey: nil)
    }
}

इसका इस्तेमाल कैसे करें:

    // You can use it with all kind of UIViews e.g. UIButton, UILabel, UIImage, UIImageView, ...
    imageView.flash(animation: .opacity, withDuration: 1, repeatCount: 5)
    titleLabel.flash(animation: .opacity, withDuration: 1, repeatCount: 5)

0
import UIKit

/*
 Here is simple subclass for CAAnimation which create a fadeIn animation
 */

class FadeInAdnimation: CABasicAnimation {
    override init() {
        super.init()
        keyPath = "opacity"
        duration = 2.0
        fromValue = 0
        toValue = 1
        fillMode = CAMediaTimingFillMode.forwards
        isRemovedOnCompletion = false
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
}

/*
 Example of usage
 */

class ViewController: UIViewController {

    weak var label: UILabel!

    override func loadView() {
        let view = UIView()
        view.backgroundColor = .white

        let label = UILabel()
        label.alpha = 0
        label.frame = CGRect(x: 150, y: 200, width: 200, height: 20)
        label.text = "Hello World!"
        label.textColor = .black
        view.addSubview(label)
        self.label = label

        let button = UIButton(type: .custom)
        button.frame = CGRect(x: 0, y: 250, width: 300, height: 100)
        button.setTitle("Press to Start FadeIn", for: UIControl.State())
        button.backgroundColor = .red
        button.addTarget(self, action: #selector(startFadeIn), for: .touchUpInside)
        view.addSubview(button)

        self.view = view
    }

    /*
     Animation in action
     */
    @objc private func startFadeIn() {
        label.layer.add(FadeInAdnimation(), forKey: "fadeIn")
    }

}

0

स्विफ्ट 5

अन्य उत्तर सही हैं, लेकिन मेरे मामले में मैं (भी अन्य गुणों को संभालने की ज़रूरत alpha, animate, completion)। इस वजह से, मैंने नीचे दिए गए इन मापदंडों को उजागर करने के लिए थोड़ा संशोधित किया:

extension UIView {
    /// Helper function to update view's alpha with animation
    /// - Parameter alpha: View's alpha
    /// - Parameter animate: Indicate alpha changing with animation or not
    /// - Parameter duration: Indicate time for animation
    /// - Parameter completion: Completion block after alpha changing is finished
    func set(alpha: CGFloat, animate: Bool, duration: TimeInterval = 0.3, completion: ((Bool) -> Void)? = nil) {
        let animation = { (view: UIView) in
            view.alpha = alpha
        }
    
        if animate {
            UIView.animate(withDuration: duration, animations: {
                animation(self)
            }, completion: { finished in
                completion?(finished)
            })
        } else {
            layer.removeAllAnimations()
            animation(self)
            completion?(true)
        }
    }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.