实现ViewController圆形转场遇Xcode报错:条件中的变量绑定需初始化器
解决"Variable binding in a condition requires an initializer"错误
嘿,我来帮你搞定这个圆形转场的错误!这个报错主要是代码里有两处语法和逻辑问题,咱们一步步捋清楚:
问题1:未初始化的变量直接用于判断
你在animateTransition方法里重新定义了var CircularTransitionMode: CircularTransitionMode,但没给它赋值就直接用if CircularTransitionMode == .present做判断——Swift要求变量必须初始化后才能使用,而且你完全不需要重新定义这个变量,直接用类里已经声明好的transition属性就行啦。
问题2:可选绑定的语法错误
你写的if case let presentedView == transitionContext.view(forKey: UITransitionContextViewKey.to)是错误的语法,view(forKey:)返回的是可选类型的UIView,正确的可选绑定应该用if let,而不是if case let ... ==这种写法。
修正后的完整代码
import UIKit class CircularTransition: NSObject { var circle = UIView() var startingPoint = CGPoint.zero { didSet { circle.center = startingPoint } } var circleColor = UIColor.white var duration = 0.3 enum CircularTransitionMode: Int { case present, dismiss, pop } var transition: CircularTransitionMode = .present } extension CircularTransition: UIViewControllerAnimatedTransitioning { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { return duration } func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { let containerView = transitionContext.containerView // 直接使用类的transition属性,无需重新定义变量 if transition == .present { // 正确的可选绑定方式获取目标视图 if let presentedView = transitionContext.view(forKey: .to) { let viewCenter = presentedView.center let viewSize = presentedView.frame.size circle = UIView() // 补全present转场的基础动画逻辑 circle.frame = CGRect(origin: startingPoint, size: CGSize(width: 0, height: 0)) circle.layer.cornerRadius = 0 circle.backgroundColor = circleColor containerView.addSubview(circle) presentedView.center = startingPoint presentedView.transform = CGAffineTransform(scaleX: 0.001, y: 0.001) presentedView.alpha = 0 containerView.addSubview(presentedView) UIView.animate(withDuration: duration, animations: { self.circle.frame = CGRect(origin: CGPoint(x: viewCenter.x - viewSize.width/2, y: viewCenter.y - viewSize.height/2), size: viewSize) self.circle.layer.cornerRadius = viewSize.width/2 presentedView.transform = .identity presentedView.alpha = 1 }) { (_) in self.circle.removeFromSuperview() transitionContext.completeTransition(true) } } } else { // 补全dismiss转场的基础动画逻辑 if let dismissedView = transitionContext.view(forKey: .from) { let viewCenter = dismissedView.center let viewSize = dismissedView.frame.size circle.frame = CGRect(origin: CGPoint(x: viewCenter.x - viewSize.width/2, y: viewCenter.y - viewSize.height/2), size: viewSize) circle.layer.cornerRadius = viewSize.width/2 circle.backgroundColor = circleColor containerView.addSubview(circle) UIView.animate(withDuration: duration, animations: { self.circle.frame = CGRect(origin: self.startingPoint, size: CGSize(width: 0, height: 0)) self.circle.layer.cornerRadius = 0 dismissedView.transform = CGAffineTransform(scaleX: 0.001, y: 0.001) dismissedView.alpha = 0 }) { (_) in dismissedView.removeFromSuperview() self.circle.removeFromSuperview() transitionContext.completeTransition(true) } } } } }
额外说明
我还给你补全了present和dismiss的基础动画逻辑,这样你就能直接看到圆形转场的效果了:
- Present时,从起点的小圆放大覆盖到目标视图,同时目标视图从缩小透明状态恢复正常
- Dismiss时,从当前视图缩小到起点的小圆,同时当前视图变透明消失
内容的提问来源于stack exchange,提问作者gflo
相关产品推荐
相关产品推荐

