如何在iOS中通过自定义转换解决此问题?

如何在iOS中通过自定义转换解决此问题?,ios,swift,uiviewanimationtransition,Ios,Swift,Uiviewanimationtransition,我构建了一个类来实现视图控制器之间的循环转换。当我点击按钮导航到另一个视图控制器时,一个圆圈从按钮开始增长,直到它用新的控制器填满屏幕。当我关闭视图控制器时,我希望这个圆缩小回原始位置。它也在工作。唯一的问题是,当“关闭”正在进行时,圆圈收缩时的屏幕背面完全是黑色的,动画完成后,新的viewController突然出现 以下是一些效果照片: 以下是自定义类的代码: class customTransition: NSObject, UIViewControllerAnimatedTransit

我构建了一个类来实现视图控制器之间的循环转换。当我点击按钮导航到另一个视图控制器时,一个圆圈从按钮开始增长,直到它用新的控制器填满屏幕。当我关闭视图控制器时,我希望这个圆缩小回原始位置。它也在工作。唯一的问题是,当“关闭”正在进行时,圆圈收缩时的屏幕背面完全是黑色的,动画完成后,新的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
但是当我设置这一行时,它完全忽略了动画转换,我不知道为什么。。。 `

委托方法:

  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
}
我错过了什么?有什么建议吗?
没有使用故事板,只需编写代码。

如果不使用navigationController,则必须在presentedviewController中使用.custom模式

 import UIKit

            class TransViewController: UIViewController {

                override func viewDidLoad() {
                    super.viewDidLoad()

                    // Do any additional setup after loading the view.
                }
                 let circularTransition = customTransition()

                @IBOutlet var presentButton : UIButton!

             @IBAction   func handlePresent(sender: UIButton){

                if let secondVC = storyboard?.instantiateViewController(withIdentifier: "next"){
                    secondVC.modalPresentationStyle = .custom
                    secondVC.transitioningDelegate = self
                    present(secondVC, animated: true, completion: nil)
                }
                }

            }


            class BackViewController: UIViewController {

                @IBAction   func dismissMe(sender: UIButton){
                    self.dismiss(animated: true, completion: nil)
                    }

            }

            extension TransViewController: UIViewControllerTransitioningDelegate {

                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
                }

            }
如果没有“从”或“到”视图,则使用“从”和“到”视图

   func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

    let container = transitionContext.containerView
    var to : UIView!
    var from : UIView!
    to = transitionContext.view(forKey: UITransitionContextViewKey.to)
    if to == nil {to = container}
    from = transitionContext.view(forKey: UITransitionContextViewKey.from)
    if from == nil {from = container}
其余的都一样:

 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)
        }
    }
}  

我认为您看到这个问题是因为您使用的是
present
,而不是。我建议尝试使用navigationController来推/弹出ViewController,并在显示ViewController时应用动画。因此,您可以在没有动画的情况下从NavController推/弹出VC。但是,VC本身会在显示第二个控制器在第一个控制器上的循环显示代码时应用所需的动画。还请添加您如何取消第二个并尝试转换回第一个。
 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)
        }
    }
}