Saya menetapkan nilai teks baru ke a UILabel
. Saat ini, teks baru muncul dengan baik. Namun, saya ingin menambahkan beberapa animasi saat teks baru muncul. Saya bertanya-tanya apa yang bisa saya lakukan untuk menghidupkan tampilan teks baru.
Saya menetapkan nilai teks baru ke a UILabel
. Saat ini, teks baru muncul dengan baik. Namun, saya ingin menambahkan beberapa animasi saat teks baru muncul. Saya bertanya-tanya apa yang bisa saya lakukan untuk menghidupkan tampilan teks baru.
Jawaban:
Saya ingin tahu apakah itu berfungsi, dan itu bekerja dengan sempurna!
Objektif-C
[UIView transitionWithView:self.label
duration:0.25f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.label.text = rand() % 2 ? @"Nice nice!" : @"Well done!";
} completion:nil];
Swift 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)
Untuk mencapai benar cross-larut transisi (label lama memudar sementara label baru memudar dalam), Anda tidak ingin memudar untuk tak terlihat. Ini akan menghasilkan flicker yang tidak diinginkan bahkan jika teks tidak berubah .
Gunakan pendekatan ini sebagai gantinya:
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"
Lihat juga: Menghidupkan teks UILabel di antara dua angka?
Demonstrasi di iOS 10, 9, 8:
Diuji dengan Xcode 8.2.1 & 7.1 , ObjectiveC di iOS 10 hingga 8.0 .
â–º Untuk mengunduh proyek lengkap, cari SO-3073520 di Swift Recipes .
-addAnimation:forKey
untuk label itu, lalu ubah teks labelnya.
Cara yang tepat untuk memudar label UIL (atau UIView dalam hal ini) adalah dengan menggunakan a Core Animation Transition
. Ini tidak akan berkedip, juga tidak akan pudar menjadi hitam jika kontennya tidak berubah.
Solusi portabel dan bersih adalah dengan menggunakan Extension
in Swift (aktifkan elemen yang terlihat sebelum berubah)
// 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)
}
}
Doa terlihat seperti ini:
// This will fade
aLabel.fadeTransition(0.4)
aLabel.text = "text"
â–º Temukan solusi ini di GitHub dan detail tambahan tentang Resep Swift .
MIT
lisensi menjamin Cocoapod Anda dapat digunakan secara bebas oleh semua orang dan siapa saja.
karena iOS4 dapat dengan jelas dilakukan dengan blok:
[UIView animateWithDuration:1.0
animations:^{
label.alpha = 0.0f;
label.text = newText;
label.alpha = 1.0f;
}];
Berikut adalah kode untuk membuatnya berfungsi.
[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];
Solusi Ekstensi UILabel
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)
}
}
Cukup dipanggil fungsi oleh
uiLabel.textWithAnimation(text: "text you want to replace", duration: 0.2)
Terima kasih untuk semua tipsnya kawan. Semoga ini bisa membantu dalam jangka panjang
Swift versi 4.2 dari solusi SwiftArchitect di atas (berfungsi dengan baik):
// 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)
}
}
Doa:
// This will fade
aLabel.fadeTransition(0.4)
aLabel.text = "text"
Swift 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"
})
ATAU
UIView.animateWithDuration(0.2, animations: {
self.sampleLabel.alpha = 1
}, completion: {
(value: Bool) in
self.sampleLabel.alpha = 0.2
})
Dengan Swift 5, Anda dapat memilih salah satu dari dua contoh kode Playground berikut untuk menganimasikan UILabel
perubahan teks Anda dengan beberapa animasi lintas silang.
UIView
's transition(with:duration:options:animations:completion:)
metode kelasimport 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
CATransition
dan CALayer
's add(_:forKey:)
metodeimport 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
Solusi Swift 4.2 (mengambil jawaban 4.0 dan memperbarui kompilasi enum baru)
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"
}
Nilai default sistem 0,25 untuk duration
dan .curveEaseInEaseOut untuk timingFunction
sering lebih disukai untuk konsistensi di seluruh animasi, dan dapat dihilangkan:
let animation = CATransition()
label.layer.add(animation, forKey: nil)
label.text = "New text"
yang sama dengan menulis ini:
let animation = CATransition()
animation.duration = 0.25
animation.timingFunction = .curveEaseInEaseOut
label.layer.add(animation, forKey: nil)
label.text = "New text"
Ini adalah metode ekstensi C # UIView yang didasarkan pada kode @ SwiftArchitect. Ketika tata letak otomatis terlibat dan kontrol perlu bergerak tergantung pada teks label, kode panggilan ini menggunakan Superview label sebagai tampilan transisi, bukan label itu sendiri. Saya menambahkan ekspresi lambda untuk tindakan agar lebih dienkapsulasi.
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();
}
Kode panggilan:
labelSuperview.FadeTransition( 0.5d, () =>
{
if ( condition )
label.Text = "Value 1";
else
label.Text = "Value 2";
} );
Jika Anda ingin melakukan ini Swift
dengan penundaan, coba ini:
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
})
}
})
}
menggunakan fungsi berikut yang dibuat oleh @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)
}
yang akan menjadi ini di Swift 3
func delay(_ delay:Double, closure:()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.after(when: when, execute: closure)
}
Ada satu solusi lagi untuk mencapai ini. Itu dijelaskan di sini . Idenya adalah fungsi subclassing UILabel
dan override action(for:forKey:)
dengan cara berikut:
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)
}
}
Contoh penggunaan:
// 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!"