2017-07-28 19 views
0

Ich habe viele verwandte Themen zu SO (und anderswo) gefunden, konnte aber immer noch keine Lösung für mein Problem finden. Ich möchte eine benutzerdefinierte Warnung in meiner Ansicht mit UIViewControllerTransitioningDelegate anzeigen. So zuerst, in meinen ersten View-Controller, hier ist der Ruf:UIViewControllerAnimatedTransitioning: Bildschirm wird immer schwarz unter benutzerdefinierte Ansicht

@IBAction func tappedButton(_ sender: Any) { 
    MyAlertViewController.presentIn(viewController: self) 
} 

Und hier der Code von MyAlertViewController:

import UIKit 

open class MyAlertViewController: UIViewController, UIViewControllerTransitioningDelegate { 

    @IBOutlet weak var overlayView: UIView? 
    @IBOutlet weak var alertView: UIView? 
    @IBOutlet weak var alertCenterYConstraint: NSLayoutConstraint? 

    public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 
     super.init(nibName: "MyAlertView", bundle: nil) 
     self.transitioningDelegate = self 
    } 

    required public init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    static func presentIn(viewController: UIViewController) { 
     let alertViewController = MyAlertViewController() 

     if Thread.isMainThread { 
      viewController.present(alertViewController, animated: true, completion: nil) 
     } else { 
      DispatchQueue.main.async { 
       viewController.present(alertViewController, animated: true, completion: nil) 
      } 
     } 
    } 

    public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return MyDismissAlertViewAnimationController() 
    } 

    public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 
     return MyPresentAlertViewAnimationController() 
    } 
} 

class MyPresentAlertViewAnimationController: NSObject, UIViewControllerAnimatedTransitioning { 
    public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 
     return 0.3 
    } 

    public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 
     let toViewController: MyAlertViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) as! MyAlertViewController 
     let duration = self.transitionDuration(using: transitionContext) 

     let containerView = transitionContext.containerView 
     toViewController.view.frame = containerView.frame 
     containerView.addSubview(toViewController.view) 

     toViewController.overlayView?.alpha = 0.0 
     UIView.animate(withDuration: duration, animations: { 
      toViewController.overlayView?.alpha = 0.6 
     }) 

     let finishFrame = toViewController.alertView?.frame 
     var startingFrame = finishFrame 
     startingFrame?.origin.y = -((finishFrame?.height)!) 
     toViewController.alertView?.frame = startingFrame! 

     UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.7, initialSpringVelocity: 1.0, options: .layoutSubviews, animations: { 
      toViewController.alertView?.frame = finishFrame! 
     }, completion: { result in 
      transitionContext.completeTransition(result) 
     }) 
    } 
} 

class MyDismissAlertViewAnimationController: NSObject, UIViewControllerAnimatedTransitioning { 
    public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 
     return 0.3 
    } 

    public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { 
     let fromViewController: MyAlertViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) as! MyAlertViewController 
     let duration = self.transitionDuration(using: transitionContext) 

     UIView.animate(withDuration: duration, animations: { 
      fromViewController.overlayView?.alpha = 0.0 
     }) 

     var finishFrame = fromViewController.alertView?.frame 
     finishFrame?.origin.y = -(finishFrame?.height)! 
     finishFrame?.origin.y = fromViewController.isDismissingByBottom ? fromViewController.view.frame.size.height : -(finishFrame?.height)! 

     UIView.animate(withDuration: duration, delay: 0.0, usingSpringWithDamping: 1.0, initialSpringVelocity: 1.0, options: .layoutSubviews, animations: { 
      fromViewController.alertView?.frame = finishFrame! 
     }, completion: { result in 
      transitionContext.completeTransition(true) 
     }) 
    } 
} 

Die Animation funktioniert gut, der schwarze Bildschirm erscheint nur nach dem Aufruf von completeTransition() wie Sie unten sehen können:

enter image description here

Danke für Ihre Hilfe ...

Antwort

1

Ich glaube, Sie müssen entweder Ihre Hintergrundfarbe wie so:

self.view.backgroundColor = .clear 

Diese vergewissert sich der Hintergrund, den Sie sehen, ist nicht nur die Hintergrundfarbe Ihrer modal.

Oder die präsentierenden View-Controller verhindern vom Bildschirm entfernt werden, indem der modalen Präsentationsstil overCurrentContext

self.modalPresentationStyle = .overCurrentContext 
+0

Vielen Dank! Das Hinzufügen von 'alertViewController.modalPresentationStyle = .overCurrentContext' in der Funktion' presentIn() 'löste das Problem. – Rob

Verwandte Themen