如何通过TabBarViewController的按钮控制UIView脉冲动画的启停
问题修复方案
存在的问题
- 按钮点击事件未正确绑定:middleButton初始化闭包执行时实例尚未完成创建,此时绑定target指向错误,同时addTarget行存在缺失右括号的语法错误,导致点击按钮无法触发响应方法
object属性未赋值:声明的MainViewObject!类型属性未绑定实际实例,值为nil,调用动画方法无任何效果- 动画配置缺失必要参数:CAAnimation默认动画结束后自动移除,未设置持久化参数会导致动画无法持续运行
- 停止动画逻辑冗余:移除图层动画不需要包裹UIView动画块
修复步骤
1. 修复按钮初始化与事件绑定
将addTarget逻辑移到viewDidLoad中执行,补全语法错误,同时在合适位置给object属性赋值:
class TabbarViewController: UITabBarController { var object: MainViewObject! let middleButton: UIButton = { let btn = UIButton(frame: CGRect(x: (UIScreen.main.bounds.width / 2) - 32, y: -8, width: 65, height: 65)) btn.setImage(UIImage(named: "play"), for: .normal) btn.layer.shadowColor = UIColor.black.cgColor btn.layer.shadowOpacity = 0.1 btn.layer.shadowOffset = CGSize(width: 4, height: 4) btn.backgroundColor = Colors.mainColor btn.layer.cornerRadius = 32 btn.tintColor = .clear return btn }() override func viewDidLoad() { super.viewDidLoad() // 实例初始化完成后再绑定点击事件 middleButton.addTarget(self, action:#selector(menuButtonAction), for: .touchUpInside) // 绑定MainViewController中的MainViewObject实例,此处示例根据你实际层级调整 if let mainVC = viewControllers?.first as? MainViewController { // 替换为你MainViewController中持有MainViewObject的属性名 self.object = mainVC.mainViewObject } } // 原有menuButtonAction等逻辑保持不变 }
2. 修复动画逻辑
补全动画持久化参数,添加空值判断避免崩溃,简化停止逻辑:
extension TabbarViewController { func pulseAnimationStart() { guard let object = object else { return } // 先移除旧动画避免重复添加 object.centerContainerView.layer.removeAnimation(forKey: "pulse") let fadingAnimation = CABasicAnimation(keyPath: "opacity") fadingAnimation.fromValue = 1 fadingAnimation.toValue = 0.6 // 可按需调整透明度下限 fadingAnimation.isRemovedOnCompletion = false let expandingAnimation = CABasicAnimation(keyPath: "transform.scale") expandingAnimation.fromValue = 1 expandingAnimation.toValue = 1.1 expandingAnimation.isRemovedOnCompletion = false let animationGroup = CAAnimationGroup() animationGroup.animations = [expandingAnimation, fadingAnimation] animationGroup.duration = 1.5 animationGroup.repeatCount = .infinity animationGroup.isRemovedOnCompletion = false animationGroup.fillMode = .forwards object.centerContainerView.layer.add(animationGroup, forKey: "pulse") } func pulseAnimationStop() { guard let object = object else { return } object.centerContainerView.layer.removeAnimation(forKey: "pulse") } }
内容的提问来源于stack exchange,提问作者zero_m
相关产品推荐
相关产品推荐

