ฉันกำลังตั้งค่าข้อความใหม่เป็นUILabel
ไฟล์. ขณะนี้ข้อความใหม่ปรากฏขึ้นตามปกติ อย่างไรก็ตามฉันต้องการเพิ่มภาพเคลื่อนไหวเมื่อข้อความใหม่ปรากฏขึ้น ฉันสงสัยว่าฉันจะทำอะไรได้บ้างเพื่อให้ข้อความใหม่เคลื่อนไหว
ฉันกำลังตั้งค่าข้อความใหม่เป็นUILabel
ไฟล์. ขณะนี้ข้อความใหม่ปรากฏขึ้นตามปกติ อย่างไรก็ตามฉันต้องการเพิ่มภาพเคลื่อนไหวเมื่อข้อความใหม่ปรากฏขึ้น ฉันสงสัยว่าฉันจะทำอะไรได้บ้างเพื่อให้ข้อความใหม่เคลื่อนไหว
คำตอบ:
ฉันสงสัยว่ามันใช้งานได้หรือไม่และทำงานได้อย่างสมบูรณ์แบบ!
Objective-C
[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)
เพื่อให้เกิดการเปลี่ยนแปลงข้ามการละลายอย่างแท้จริง (ฉลากเก่าจะจางหายไปในขณะที่ฉลากใหม่จางลง) คุณไม่ต้องการให้เลือนหายไปจนมองไม่เห็น มันจะส่งผลให้เกิดการสั่นไหวที่ไม่ต้องการแม้ว่าข้อความจะไม่เปลี่ยนแปลงก็ตามก็ตาม
ใช้แนวทางนี้แทน:
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"
ดูเพิ่มเติม: ทำให้ ข้อความ UILabel เคลื่อนไหวระหว่างตัวเลขสองตัว?
การสาธิตใน iOS 10, 9, 8:
ทดสอบกับXcode 8.2.1 และ 7.1 , objectivecบนiOS 10-8.0
►การดาวน์โหลดโครงการเต็มรูปแบบค้นหาSO-3073520ในสวิฟท์สูตร
-addAnimation:forKey
กับป้ายนั้นจากนั้นเปลี่ยนข้อความของป้ายกำกับ
วิธีที่เหมาะสมในการทำให้ UILabel จางหายไป (หรือ UIView ใด ๆ สำหรับเรื่องนั้น) คือการใช้ไฟล์ Core Animation Transition
. สิ่งนี้จะไม่สั่นไหวและจะไม่จางหายไปเป็นสีดำหากเนื้อหาไม่เปลี่ยนแปลง
โซลูชันแบบพกพาและสะอาดคือการใช้Extension
Swift (เรียกใช้ก่อนที่จะเปลี่ยนองค์ประกอบที่มองเห็นได้)
// 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"
►หาวิธีการแก้ปัญหานี้บนGitHubและรายละเอียดเพิ่มเติมเกี่ยวกับสวิฟท์สูตร
MIT
ใบอนุญาตดังกล่าวรับประกันว่า Cocoapod ของคุณสามารถใช้ได้อย่างอิสระโดยทุกคนและทุกคน
เนื่องจาก iOS4 สามารถทำได้ด้วยบล็อก:
[UIView animateWithDuration:1.0
animations:^{
label.alpha = 0.0f;
label.text = newText;
label.alpha = 1.0f;
}];
นี่คือรหัสที่จะทำให้งานนี้
[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];
โซลูชันส่วนขยาย 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)
}
}
เรียกง่ายๆว่าฟังก์ชั่นโดย
uiLabel.textWithAnimation(text: "text you want to replace", duration: 0.2)
ขอบคุณสำหรับเคล็ดลับทั้งหมด หวังว่านี่จะช่วยได้ในระยะยาว
โซลูชันของ SwiftArchitect เวอร์ชัน Swift 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"
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"
})
หรือ
UIView.animateWithDuration(0.2, animations: {
self.sampleLabel.alpha = 1
}, completion: {
(value: Bool) in
self.sampleLabel.alpha = 0.2
})
ด้วย Swift 5 คุณสามารถเลือกหนึ่งในสองตัวอย่างโค้ด Playground ต่อไปนี้เพื่อทำให้UILabel
การเปลี่ยนแปลงข้อความของคุณเคลื่อนไหวด้วยภาพเคลื่อนไหวที่ละลายได้
UIView
เป็น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
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
โซลูชัน Swift 4.2 (รับ 4.0 คำตอบและอัปเดตสำหรับ enums ใหม่เพื่อรวบรวม)
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"
}
ค่าดีฟอลต์ของระบบ 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"
นี่คือวิธีการขยาย C # UIView ที่ใช้รหัสของ @ SwiftArchitect เมื่อมีส่วนเกี่ยวข้องกับการจัดวางอัตโนมัติและการควบคุมจำเป็นต้องย้ายโดยขึ้นอยู่กับข้อความของป้ายกำกับรหัสการเรียกนี้จะใช้ Superview ของป้ายกำกับเป็นมุมมองการเปลี่ยนแทนป้ายกำกับเอง ฉันเพิ่มนิพจน์แลมบ์ดาสำหรับการกระทำเพื่อให้มีการห่อหุ้มมากขึ้น
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";
} );
หากคุณต้องการดำเนินการ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)
}
ซึ่งจะกลายเป็นสิ่งนี้ใน Swift 3
func delay(_ delay:Double, closure:()->()) {
let when = DispatchTime.now() + delay
DispatchQueue.main.after(when: when, execute: closure)
}
มีอีกวิธีหนึ่งที่จะบรรลุเป้าหมายนี้ มันถูกอธิบายไว้ที่นี่ แนวคิดคือการแบ่งคลาสย่อย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!"