उइबेल में चेतन पाठ परिवर्तन


133

मैं एक नया पाठ मान सेट कर रहा हूँ a UILabel। वर्तमान में, नया पाठ ठीक दिखाई देता है। हालाँकि, मैं नया पाठ प्रकट होने पर कुछ एनीमेशन जोड़ना चाहूंगा। मैं सोच रहा हूँ कि नए पाठ की उपस्थिति को चेतन करने के लिए मैं क्या कर सकता हूँ।


स्विफ्ट 5 के लिए, मेरा जवाब देखें जो आपकी समस्या को हल करने के 2 अलग-अलग तरीके दिखाता है।
इमानो पेटिट

जवाबों:


177

मुझे आश्चर्य है कि अगर यह काम करता है, और यह पूरी तरह से काम करता है!

उद्देश्य सी

[UIView transitionWithView:self.label 
                  duration:0.25f 
                   options:UIViewAnimationOptionTransitionCrossDissolve 
                animations:^{

    self.label.text = rand() % 2 ? @"Nice nice!" : @"Well done!";

  } completion:nil];

स्विफ्ट 3, 4, 5

UIView.transition(with: label,
              duration: 0.25,
               options: .transitionCrossDissolve,
            animations: { [weak self] in
                self?.label.text = (arc4random()() % 2 == 0) ? "One" : "Two"
         }, completion: nil)

16
ध्यान दें कि TransitionCrossDissolve इस काम की कुंजी है।
अकरु

7
आपको UIView एनीमेशन ब्लॉक में [कमजोर आत्म] की आवश्यकता नहीं है। देखें stackoverflow.com/a/27019834/511299
सनकास

162

उद्देश्य सी

एक वास्तविक क्रॉस-भंग संक्रमण ( नया लेबल लुप्त होते समय पुराना लेबल लुप्त हो जाना ) प्राप्त करने के लिए, आप अदृश्य को फीका नहीं चाहते। यह अवांछित झिलमिलाहट में परिणाम होगा भले ही पाठ अपरिवर्तित हो

इसके बजाय इस दृष्टिकोण का उपयोग करें:

CATransition *animation = [CATransition animation];
animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
animation.type = kCATransitionFade;
animation.duration = 0.75;
[aLabel.layer addAnimation:animation forKey:@"kCATransitionFade"];

// This will fade:
aLabel.text = "New"

इसे भी देखें: दो नंबरों के बीच चेतन उलाबेल पाठ?

IOS 10, 9, 8 में प्रदर्शन:

रिक्त, फिर 1 से 5 फीका संक्रमण


Xcode 8.2.1 और 7.1 के साथ परीक्षण किया गया , iOS 10 पर 8.0 पर ObjectiveC

, पूर्ण परियोजना को डाउनलोड करने के लिए, स्विफ्ट व्यंजनों में SO-3073520 खोजें


जब मैं एक ही समय में दो लेबल सेट करता हूं तो यह सिम्युलेटर पर झिलमिलाहट देता है।
ह्यूगी

1
संभवतः दुरुपयोग? मेरे दृष्टिकोण का बिंदु 2 लेबल का उपयोग नहीं करना है। आप -addAnimation:forKeyउस लेबल पर एकल लेबल का उपयोग करते हैं , फिर लेबल के पाठ को बदलते हैं।
स्विफ्टआर्किटेक्ट

@ConfusedVorlon, कृपया अपना विवरण सत्यापित करें। और स्विफ्टऑर्किटेक्ट . com / recipes / #SO-3073520 पर पोस्ट किए गए प्रोजेक्ट के खिलाफ जांच करें ।
स्विफ्टआर्किटेक्ट

मुझे अतीत में इस पर छड़ी का गलत अंत मिल सकता है। मैंने सोचा था कि आप परत के लिए एक बार संक्रमण को परिभाषित कर सकते हैं, फिर बाद में बदलाव कर सकते हैं और एक 'मुक्त' फीका प्राप्त कर सकते हैं। ऐसा लगता है कि आपको प्रत्येक परिवर्तन पर फीका निर्दिष्ट करना होगा। इसलिए - बशर्ते आप हर बार संक्रमण को बुलावा दें, यह iOS9 पर मेरे परीक्षण में ठीक काम करता है।
कन्फ्यूज्ड वोरलोन

कृपया भ्रामक निकालें, लेकिन iOS9 में काम नहीं करता है अगर आपको लगता है कि यह अब उचित नहीं है। धन्यवाद।
स्विफ्टआर्किटेक्ट

134

स्विफ्ट 4

UILabel को फीका करने का उचित तरीका (या उस मामले के लिए कोई भी UIView) a का उपयोग करना है Core Animation Transition। यह झिलमिलाहट नहीं करेगा, न ही सामग्री के अपरिवर्तित होने पर यह काला हो जाएगा।

एक पोर्टेबल और स्वच्छ समाधान एक Extensionस्विफ्ट का उपयोग करना है (पूर्व बदलते तत्वों को देखें)

// Usage: insert view.fadeTransition right before changing content


extension UIView {
    func fadeTransition(_ duration:CFTimeInterval) {
        let animation = CATransition()
        animation.timingFunction = CAMediaTimingFunction(name:
            CAMediaTimingFunctionName.easeInEaseOut)
        animation.type = CATransitionType.fade
        animation.duration = duration
        layer.add(animation, forKey: CATransitionType.fade.rawValue)
    }
}

आमंत्रण इस तरह दिखता है:

// This will fade
aLabel.fadeTransition(0.4)
aLabel.text = "text"

रिक्त, फिर 1 से 5 फीका संक्रमण


H GitHub पर इस समाधान का पता लगाएं और स्विफ्ट व्यंजनों पर अतिरिक्त विवरण ।


1
हैलो, मैंने अपनी परियोजना में आपके कोड का उपयोग किया, सोचा कि आपकी रुचि हो सकती है: github.com/goktugyil/CozyLoadingActivity
Esqarrouth

अच्छा - यदि आप एमआईटी लाइसेंस (उसी लाइसेंस का वकील-टॉक संस्करण) का उपयोग कर सकते हैं, तो इसका उपयोग व्यावसायिक ऐप में किया जा सकता है ...
SwiftArchitect

मैं वास्तव में लाइसेंस सामान के बारे में नहीं समझता। अब व्यावसायिक ऐप में लोगों को इसका उपयोग करने से क्या रोकता है?
एसकर्रौथ

2
कई कंपनियों ने मानक लाइसेंस पर सूचीबद्ध जब तक उपयोग नहीं कर सकते opensource.org/licenses और कुछ केवल का पालन Cocoapods शामिल करेंगे opensource.org/licenses/MIT । यह MITलाइसेंस आपके कोकोपोड की गारंटी देता है कि इसका उपयोग हर कोई और किसी के द्वारा स्वतंत्र रूप से किया जा सकता है।
स्विफ्टआर्किटेक्ट

2
वर्तमान डब्ल्यूटीएफ लाइसेंस के साथ मुद्दा यह है कि यह आपके आधार को कवर नहीं करता है: शुरुआत के लिए, यह आपको लेखक (कॉपीराइट) के रूप में दावा नहीं करता है, और इस तरह, यह साबित करता है कि आप विशेषाधिकारों को दूर दे सकते हैं। एमआईटी लाइसेंस में, आप पहले स्वामित्व का दावा करते हैं, जिसका उपयोग आप अधिकारों को त्यागने के लिए करते हैं। यदि आप पेशेवरों को अपने कोड का लाभ उठाना चाहते हैं, और अपने ओपन सोर्स प्रयास में भाग लेना चाहते हैं, तो आपको वास्तव में एमआईटी पर पढ़ना चाहिए।
स्विफ्टआर्किटेक्ट सेप

20

iOS4 के बाद से यह स्पष्ट रूप से ब्लॉक के साथ किया जा सकता है:

[UIView animateWithDuration:1.0
                 animations:^{
                     label.alpha = 0.0f;
                     label.text = newText;
                     label.alpha = 1.0f;
                 }];

11
क्रॉस-फेड संक्रमण नहीं।
SwiftArchitect

17

इस कार्य को करने के लिए यहाँ कोड है।

[UIView beginAnimations:@"animateText" context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseIn];
[UIView setAnimationDuration:1.0f];
[self.lbl setAlpha:0];
[self.lbl setText:@"New Text";
[self.lbl setAlpha:1];
[UIView commitAnimations];

3
यह फीका नहीं है। यह एक फीका है, पूरी तरह से गायब हो जाता है, फिर फीका हो जाता है। यह मूल रूप से एक धीमी गति वाली झिलमिलाहट है, लेकिन यह अभी भी एक झिलमिलाहट है।
स्विफ्टआर्किटेक्ट

18
कृपया अपना UILabels lbl
rigdonmr

5

UILabel Extension Solution

extension UILabel{

  func animation(typing value:String,duration: Double){
    let characters = value.map { $0 }
    var index = 0
    Timer.scheduledTimer(withTimeInterval: duration, repeats: true, block: { [weak self] timer in
        if index < value.count {
            let char = characters[index]
            self?.text! += "\(char)"
            index += 1
        } else {
            timer.invalidate()
        }
    })
  }


  func textWithAnimation(text:String,duration:CFTimeInterval){
    fadeTransition(duration)
    self.text = text
  }

  //followed from @Chris and @winnie-ru
  func fadeTransition(_ duration:CFTimeInterval) {
    let animation = CATransition()
    animation.timingFunction = CAMediaTimingFunction(name:
        CAMediaTimingFunctionName.easeInEaseOut)
    animation.type = CATransitionType.fade
    animation.duration = duration
    layer.add(animation, forKey: CATransitionType.fade.rawValue)
  }

}

बस कहा जाता है फ़ंक्शन द्वारा

uiLabel.textWithAnimation(text: "text you want to replace", duration: 0.2)

सभी युक्तियों के लिए धन्यवाद। उम्मीद है कि इससे लंबी अवधि में मदद मिलेगी


4

SwiftArchitect के उपरोक्त समाधान का स्विफ्ट 4.2 संस्करण (महान काम करता है):

    // Usage: insert view.fadeTransition right before changing content    

extension UIView {

        func fadeTransition(_ duration:CFTimeInterval) {
            let animation = CATransition()
            animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
            animation.type = CATransitionType.fade
            animation.duration = duration
            layer.add(animation, forKey: CATransitionType.fade.rawValue)
        }
    }

मंगलाचरण:

    // This will fade

aLabel.fadeTransition(0.4)
aLabel.text = "text"

3

स्विफ्ट 2.0:

UIView.transitionWithView(self.view, duration: 1.0, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: {
    self.sampleLabel.text = "Animation Fade1"
    }, completion: { (finished: Bool) -> () in
        self.sampleLabel.text = "Animation Fade - 34"
})

या

UIView.animateWithDuration(0.2, animations: {
    self.sampleLabel.alpha = 1
}, completion: {
    (value: Bool) in
    self.sampleLabel.alpha = 0.2
})

1
पहला काम करता है, लेकिन दूसरा अभी पूरा करने के लिए कहता है, चाहे मैं कितनी भी अवधि पार कर लूं। एक और मुद्दा यह है कि मैं किसी भी बटन को दबा नहीं सकता, जबकि मैं पहले समाधान के साथ एनिमेशन कर रहा हूं।
endavid

ऐनिमेशन करते समय इंटरैक्शन की अनुमति देने के लिए, मैंने एक विकल्प जोड़ा, विकल्प: [.TransitionCrossDissolve, .AllowUserInteraction]
17

Self.view का उपयोग करते हुए पहले विकल्प में पूरे दृश्य को बदल देता है, इसका मतलब है कि केवल TransitionCrossDissolve का उपयोग किया जा सकता है। इसके बजाय केवल पाठ को संक्रमित करना बेहतर है: "UIView.transitionWithView (self.sampleLabel, अवधि: 1.0 ..."। इसके अलावा मेरे मामले में इसने "..., पूरा: nil) के साथ बेहतर काम किया है।"
विटालि

3

स्विफ्ट 5 के साथ, आप UILabelकुछ क्रॉस डिसेबल एनीमेशन के साथ अपने पाठ परिवर्तनों को चेतन करने के लिए निम्नलिखित दो प्लेग्राउंड कोड नमूनों में से एक चुन सकते हैं ।


# 1। का उपयोग करते हुए UIView's transition(with:duration:options:animations:completion:)वर्ग विधि

import UIKit
import PlaygroundSupport

class ViewController: UIViewController {

    let label = UILabel()

    override func viewDidLoad() {
        super.viewDidLoad()

        label.text = "Car"

        view.backgroundColor = .white
        view.addSubview(label)

        label.translatesAutoresizingMaskIntoConstraints = false
        label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggle(_:)))
        view.addGestureRecognizer(tapGesture)
    }

    @objc func toggle(_ sender: UITapGestureRecognizer) {
        let animation = {
            self.label.text = self.label.text == "Car" ? "Plane" : "Car"
        }
        UIView.transition(with: label, duration: 2, options: .transitionCrossDissolve, animations: animation, completion: nil)
    }

}

let controller = ViewController()
PlaygroundPage.current.liveView = controller

# 2। का उपयोग करते हुए CATransitionऔर CALayerकी add(_:forKey:)विधि

import UIKit
import PlaygroundSupport

class ViewController: UIViewController {

    let label = UILabel()
    let animation = CATransition()

    override func viewDidLoad() {
        super.viewDidLoad()

        label.text = "Car"

        animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
        // animation.type = CATransitionType.fade // default is fade
        animation.duration = 2

        view.backgroundColor = .white
        view.addSubview(label)

        label.translatesAutoresizingMaskIntoConstraints = false
        label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggle(_:)))
        view.addGestureRecognizer(tapGesture)
    }

    @objc func toggle(_ sender: UITapGestureRecognizer) {
        label.layer.add(animation, forKey: nil) // The special key kCATransition is automatically used for transition animations
        label.text = label.text == "Car" ? "Plane" : "Car"
    }

}

let controller = ViewController()
PlaygroundPage.current.liveView = controller

दोनों एनिमेशन क्रॉसडिसोल्व जैसे ही काम करते हैं। वैसे भी इस तरह के एक वर्णनात्मक उत्तर के लिए धन्यवाद।
यश बेदी

2

४.२ समाधान (४.० उत्तर लेना और संकलन के लिए नई पहेली के लिए अद्यतन करना)

extension UIView {
    func fadeTransition(_ duration:CFTimeInterval) {
        let animation = CATransition()
        animation.timingFunction = CAMediaTimingFunction(name:
            CAMediaTimingFunctionName.easeInEaseOut)
        animation.type = CATransitionType.fade
        animation.duration = duration
        layer.add(animation, forKey: CATransitionType.fade.rawValue)
    }
}

func updateLabel() {
myLabel.fadeTransition(0.4)
myLabel.text = "Hello World"
}

2

सिस्टम डिफ़ॉल्ट मान 0.25 के लिए durationऔर .curveEaseInEaseOut के लिए timingFunctionअक्सर एनिमेशन में स्थिरता के लिए बेहतर हैं, और छोड़ा जा सकता है:

let animation = CATransition()
label.layer.add(animation, forKey: nil)
label.text = "New text"

जो इसे लिखने के समान है:

let animation = CATransition()
animation.duration = 0.25
animation.timingFunction = .curveEaseInEaseOut
label.layer.add(animation, forKey: nil)
label.text = "New text"

1

यह एक C # UIView विस्तार विधि है जो @ SwiftArchitect के कोड पर आधारित है। जब ऑटो लेआउट शामिल होता है और लेबल के पाठ के आधार पर नियंत्रण को स्थानांतरित करने की आवश्यकता होती है, तो यह कॉलिंग कोड लेबल के सुपरविवे का उपयोग लेबल के बजाय संक्रमण दृश्य के रूप में करता है। मैंने इसे और अधिक संक्षिप्त बनाने के लिए कार्रवाई के लिए एक लंबोतरा अभिव्यक्ति जोड़ी।

public static void FadeTransition( this UIView AView, double ADuration, Action AAction )
{
  CATransition transition = new CATransition();

  transition.Duration = ADuration;
  transition.TimingFunction = CAMediaTimingFunction.FromName( CAMediaTimingFunction.Linear );
  transition.Type = CATransition.TransitionFade;

  AView.Layer.AddAnimation( transition, transition.Type );
  AAction();
}

कॉलिंग कोड:

  labelSuperview.FadeTransition( 0.5d, () =>
  {
    if ( condition )
      label.Text = "Value 1";
    else
      label.Text = "Value 2";
  } );

0

यदि आप Swiftएक देरी के साथ ऐसा करने की कोशिश करेंगे:

delay(1.0) {
        UIView.transitionWithView(self.introLabel, duration: 0.25, options: [.TransitionCrossDissolve], animations: {
            self.yourLabel.text = "2"
            }, completion:  { finished in

                self.delay(1.0) {
                    UIView.transitionWithView(self.introLabel, duration: 0.25, options: [.TransitionCrossDissolve], animations: {
                        self.yourLabel.text = "1"
                        }, completion:  { finished in

                    })
                }

        })
    }

@matt - https://stackoverflow.com/a/24318861/1982051 द्वारा निर्मित निम्नलिखित फ़ंक्शन का उपयोग करना :

func delay(delay:Double, closure:()->()) {
    dispatch_after(
        dispatch_time(
            DISPATCH_TIME_NOW,
            Int64(delay * Double(NSEC_PER_SEC))
        ),
        dispatch_get_main_queue(), closure)
}

जो स्विफ्ट 3 में यह बन जाएगा

func delay(_ delay:Double, closure:()->()) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.after(when: when, execute: closure)
}

0

इसे प्राप्त करने के लिए एक और उपाय है। यह यहाँ वर्णित किया गया था । यह विचार निम्न प्रकार से फ़ंक्शन को उपवर्गित UILabelऔर अधिलेखित action(for:forKey:)कर रहा है:

class LabelWithAnimatedText: UILabel {
    override var text: String? {
        didSet {
            self.layer.setValue(self.text, forKey: "text")
        }
    }

    override func action(for layer: CALayer, forKey event: String) -> CAAction? {
        if event == "text" {
            if let action = self.action(for: layer, forKey: "backgroundColor") as? CAAnimation {
                let transition = CATransition()
                transition.type = kCATransitionFade

                //CAMediatiming attributes
                transition.beginTime = action.beginTime
                transition.duration = action.duration
                transition.speed = action.speed
                transition.timeOffset = action.timeOffset
                transition.repeatCount = action.repeatCount
                transition.repeatDuration = action.repeatDuration
                transition.autoreverses = action.autoreverses
                transition.fillMode = action.fillMode

                //CAAnimation attributes
                transition.timingFunction = action.timingFunction
                transition.delegate = action.delegate

                return transition
            }
        }
        return super.action(for: layer, forKey: event)
    }
}

उपयोग के उदाहरण:

// do not forget to set the "Custom Class" IB-property to "LabelWithAnimatedText"
// @IBOutlet weak var myLabel: LabelWithAnimatedText!
// ...

UIView.animate(withDuration: 0.5) {
    myLabel.text = "I am animated!"
}
myLabel.text = "I am not animated!"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.