【发布时间】:2018-11-17 21:55:24
【问题描述】:
我构建了一个类来实现视图控制器之间的循环转换。当我点击按钮导航到另一个视图控制器时,一个圆圈开始从按钮开始增长,直到它用新控制器填充屏幕。当我关闭视图控制器时,我预计这个圆圈会缩小回原来的位置。它也在工作。唯一的问题是,在关闭过程中,当圆圈缩小时,屏幕背面是完全黑色的,并且在动画完成后,新的 viewController 会突然出现。
以下是一些效果图:
自定义类的代码如下:
class customTransition: NSObject, UIViewControllerAnimatedTransitioning{
var duration: TimeInterval = 0.5
var startPoint = CGPoint.zero
var circle = UIView()
var circleColor = UIColor.white
enum transitMode: Int {
case presenting, dismissing
}
var transitionMode: transitMode = .presenting
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let container = transitionContext.containerView
guard let to = transitionContext.view(forKey: UITransitionContextViewKey.to) else {return}
guard let from = transitionContext.view(forKey: UITransitionContextViewKey.from) else {return}
circleColor = to.backgroundColor ?? UIColor.white
if transitionMode == .presenting {
to.translatesAutoresizingMaskIntoConstraints = false
to.center = startPoint
circle = UIView()
circle.backgroundColor = circleColor
circle.frame = getFrameForCircle(rect: to.frame)
circle.layer.cornerRadius = circle.frame.width / 2
circle.transform = CGAffineTransform(scaleX: 0.01, y: 0.01)
circle.alpha = 0
circle.addSubview(to)
to.centerXAnchor.constraint(equalTo: circle.centerXAnchor).isActive = true
to.centerYAnchor.constraint(equalTo: circle.centerYAnchor).isActive = true
to.widthAnchor.constraint(equalToConstant: to.frame.width).isActive = true
to.heightAnchor.constraint(equalToConstant: to.frame.height).isActive = true
container.addSubview(circle)
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: UIView.AnimationOptions.curveLinear, animations: {
self.circle.center = from.center
self.circle.transform = CGAffineTransform.identity
self.circle.alpha = 1
}) { (sucess) in
transitionContext.completeTransition(sucess)
}
} else if transitionMode == .dismissing {
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0, options: UIView.AnimationOptions.curveLinear, animations: {
self.circle.center = self.startPoint
self.circle.transform = CGAffineTransform(scaleX: 0.001, y: 0.001)
self.circle.alpha = 0
}) { (sucess) in
transitionContext.completeTransition(sucess)
}
}
}
func getFrameForCircle(rect: CGRect) -> CGRect{
let width = Float(rect.width)
let height = Float(rect.height)
let diameter = CGFloat(sqrtf(width * width + height * height))
let x: CGFloat = rect.midX - (diameter / 2)
let y: CGFloat = rect.midY - (diameter / 2)
return CGRect(x: x, y: y, width: diameter, height: diameter)
}
}
以及实现...
let circularTransition = customTransition()
对当前视图控制器的调用...我尝试设置secondVC.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext,但是当我设置此行时,它完全忽略了动画过渡,我不知道为什么...
`
@objc func handlePresent(sender: UIButton){
let secondVC = nextVC()
secondVC.transitioningDelegate = self
present(secondVC, animated: true, completion: nil)
}
委托方法:
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
circularTransition.startPoint = presentButton.center
circularTransition.transitionMode = .presenting
return circularTransition
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
circularTransition.transitionMode = .dismissing
circularTransition.startPoint = presentButton.center
return circularTransition
}
我在这里缺少什么?有什么建议么? 没有使用故事板,只使用代码。
【问题讨论】:
-
我认为您看到这个问题是因为您使用的是
present而不是navigationController。我建议尝试使用 navigationController 来推送/弹出 ViewController 并在 ViewController 出现时应用您的动画。因此,您可以在没有动画的情况下从 NavController 推送/弹出 VC。但是,VC 本身会在出现缩小或增长到/从一个圆圈时应用您想要的动画 -
您展示了在第一个控制器上显示第二个控制器的代码。还请添加您如何关闭第 2 次并尝试转换回第 1 次。
标签: ios swift uiviewanimationtransition