如何在同一个UILabel中通过淡入淡出轮播展示数组内的多条文本
问题原因
你的代码只显示最后一条名言,是两个问题叠加导致的:
- for循环为同步立即执行,遍历完整数组仅需几毫秒,会连续覆盖
quoteLabel.text的值,等到后续异步动画执行时,label的文本已经被替换为数组最后一个元素的内容 - 你给同一个label连续添加了多组淡入淡出动画,所有动画串行执行时,最终只有最后一次赋值的文本会被展示
修复方案
核心思路是控制动画执行顺序,等前一条名言的「淡入→停留展示→淡出」完整流程执行完毕后,再加载下一条名言,通过递归遍历数组实现即可,参考代码如下:
// 定义当前展示的名言下标 private var currentQuoteIndex = 0 // 轮播展示逻辑 private func showNextQuote() { // 数组越界判断,所有名言展示完毕可按需选择重置轮播或结束流程 guard let quotations = splashModel?.quotations, currentQuoteIndex < quotations.count else { // 如需循环轮播可打开下方两行注释 // currentQuoteIndex = 0 // showNextQuote() return } let currentQuote = quotations[currentQuoteIndex] quoteLabel.alpha = 0 quoteLabel.text = currentQuote // 淡入动画完成后停留2秒,再执行淡出,淡出完成后切换下一条 quoteLabel.fadeIn(completion: { [weak self] finished in guard let self = self, finished else { return } DispatchQueue.main.asyncAfter(deadline: .now() + 2) { self.quoteLabel.fadeOut(completion: { [weak self] finished in guard let self = self, finished else { return } self.currentQuoteIndex += 1 self.showNextQuote() }) } }) } // 拿到服务端返回的名言数组后调用该方法启动轮播即可 showNextQuote()
注意事项
- 闭包中添加
[weak self]修饰符,避免循环引用导致内存泄漏 - 可根据业务需求调整动画时长、名言停留时长
- 如果你使用的
fadeIn/fadeOut方法暂不支持completion回调,可参考以下UIView扩展实现:
extension UIView { func fadeIn(duration: TimeInterval = 0.5, completion: ((Bool) -> Void)? = nil) { UIView.animate(withDuration: duration, animations: { self.alpha = 1 }, completion: completion) } func fadeOut(duration: TimeInterval = 0.5, completion: ((Bool) -> Void)? = nil) { UIView.animate(withDuration: duration, animations: { self.alpha = 0 }, completion: completion) } }
内容的提问来源于stack exchange,提问作者Poornima Mishra
相关产品推荐
相关产品推荐

