ios - UIViewControllerAnimatedTransitioning : screen keeps getting black under custom view

标签 ios swift animation uiviewcontroller

我在 SO(和其他地方)上找到了许多相关主题,但仍然找不到解决我的问题的方法。我想使用 UIViewControllerTransitioningDelegate 在我的 View 上显示自定义警报。所以首先,在我的初始 View Controller 中,调用如下:

@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() 后出现,如下所示:

enter image description here

感谢您的帮助...

最佳答案

我认为您需要像这样设置背景颜色:

self.view.backgroundColor = .clear

这将确保您看到的背景不仅仅是模态框的背景颜色。

或者通过制作模态呈现样式 overCurrentContext 来防止呈现 View Controller 从屏幕上移除

self.modalPresentationStyle = .overCurrentContext

关于ios - UIViewControllerAnimatedTransitioning : screen keeps getting black under custom view,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45368365/

相关文章:

objective-c - 如何为 UIView 制作与 presentModalViewController 相同的动画(即 [self presentModalViewController :child animated:YES];)

ios - 延迟更新UI

ios - 判断路径是否为根目录的正则表达式

iphone - 如何调整 UITableView 的大小以自定义动态扩展 UITableViewCell

ios - Swift 软件 iOS 代码决定

android - 如何实现抽屉打开时动画到后退按钮的抽屉导航按钮(汉堡包)

ios - 应用内购买服务器模型,交易相关

ios - 使用UITableView动态显示NSManagedObject的各个属性

ios - 带有自定义 UITableViewCell 的 UITableView 中的 UITextField 中的 UIDatePicker : realtime update

javascript - 如何通过单击鼠标更改文本区域的高度