iOS 17下UIBarButtonItem的pulse符号动画失效问题(不使用UIImageView)
你的代码逻辑本身没问题,但符号动画的添加时机不对——在viewDidLoad阶段,UIBarButtonItem尚未被添加到实际视图层级中,此时调用addSymbolEffect不会触发动画效果。WWDC视频的描述没错,但未强调这个关键的时机细节。
修正方案:调整动画添加时机
把添加符号动画的代码移到按钮完成视图渲染之后执行,有两种可行方式:
方式1:在viewDidAppear中添加动画
import UIKit class ViewController: UIViewController { private var resumeButton: UIBarButtonItem? override func viewDidLoad() { super.viewDidLoad() let config = UIImage.SymbolConfiguration(scale: UIImage.SymbolScale.large) let image = UIImage(systemName: "playpause.fill", withConfiguration: config) resumeButton = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(sayHello)) toolbarItems = [resumeButton!] } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) resumeButton?.addSymbolEffect(.pulse, options: .repeating, animated: true) resumeButton?.isSymbolAnimationEnabled = true } @objc func sayHello(_ sender: UIBarButtonItem) { print("Hello: \(sender)") } }
方式2:在viewDidLoad中延迟执行动画
通过DispatchQueue.main.async把动画代码推迟到下一次主循环,确保按钮已加入视图层级:
override func viewDidLoad() { super.viewDidLoad() let config = UIImage.SymbolConfiguration(scale: UIImage.SymbolScale.large) let image = UIImage(systemName: "playpause.fill", withConfiguration: config) let resumeButton = UIBarButtonItem(image: image, style: .plain, target: self, action: #selector(sayHello)) toolbarItems = [resumeButton] // 延迟执行,确保按钮完成渲染 DispatchQueue.main.async { resumeButton.addSymbolEffect(.pulse, options: .repeating, animated: true) resumeButton.isSymbolAnimationEnabled = true } }
关于自定义UIImageView的对齐问题
如果你想通过自定义视图实现动画,别直接用UIImageView作为customView,改用UIButton包裹UIImageView——UIButton会自动适配工具栏的布局规则,解决尺寸和对齐异常的问题:
override func viewDidLoad() { super.viewDidLoad() let config = UIImage.SymbolConfiguration(scale: UIImage.SymbolScale.large) let image = UIImage(systemName: "playpause.fill", withConfiguration: config) // 用UIButton包裹UIImageView,自动适配工具栏布局 let button = UIButton(type: .system) button.setImage(image, for: .normal) button.addTarget(self, action: #selector(sayHello), for: .touchUpInside) // 给内部的UIImageView添加符号动画 if let imageView = button.imageView { imageView.addSymbolEffect(.pulse, options: .repeating, animated: true) } let resumeButton = UIBarButtonItem(customView: button) toolbarItems = [resumeButton] }
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

