我在SO(以及其他地方)找到了许多相关主题,但仍无法找到问题的解决方案。我想使用UIViewControllerTransitioningDelegate
在我的视图中显示自定义提醒。首先,在我的初始视图控制器中,这是调用:
@IBAction func tappedButton(_ sender: Any) {
MyAlertViewController.presentIn(viewController: self)
}
这里是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)
})
}
}
动画效果很好,只有在调用completeTransition()
后才能显示黑屏,如下所示:
感谢您的帮助......
答案 0 :(得分:1)
我认为您需要像这样设置背景颜色:
self.view.backgroundColor = .clear
这将确保您看到的背景不仅仅是模态的背景颜色。
或者通过制作模态演示样式overCurrentContext
self.modalPresentationStyle = .overCurrentContext