解决Viewcontroller 做为modal视图弹出时没法半透明,和底层view变黑的问题

主Viewcontroller 须要使用UIViewControllerTransitioningDelegate协议:swift

class ViewController: UIViewController ,UIViewControllerTransitioningDelegate{
    var customAnimationController:BouncePresentAnimation
    var dismiassAni : NormalDismissAnimation
    required init(coder aDecoder: NSCoder) {
        customAnimationController = BouncePresentAnimation()
        dismiassAni = NormalDismissAnimation()
        super.init(coder: aDecoder)
    }
    func animationControllerForPresentedController(presented: UIViewController!, presentingController presenting: UIViewController!, sourceController source: UIViewController!) -> UIViewControllerAnimatedTransitioning! {
        return self.customAnimationController
    }
    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return self.dismiassAni
    }
}

此时涉及到利用coder aDecoder: NSCoder初始化,因此其余地方如何引用这个viewcontroller也是个难题: iview

let loginVc = UINavigationController(rootViewController: ViewController(coder: NSCoder.empty()))
extension NSCoder {
    class func empty() -> NSCoder {
        let data = NSMutableData()
        let archiver = NSKeyedArchiver(forWritingWithMutableData: data)
        archiver.finishEncoding()
        return NSKeyedUnarchiver(forReadingWithData: data)
    }
}

弹出modal类,主要应用了动画:函数

class BouncePresentAnimation: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
        return 0.8
    }
    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        // 1. Get controllers from transition context
        let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
        let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
        // 2. Set init frame for toVC
        let finalFrame = transitionContext.finalFrameForViewController(toViewController!)
        let containerView = transitionContext.containerView()
        let realFrame = CGRectMake(finalFrame.origin.x+300, finalFrame.origin.y, finalFrame.width, finalFrame.height)
        //finalFrame.origin.x = finalFrame.origin.x + 100
        let screenBounds = UIScreen.mainScreen().bounds
        toViewController?.view.frame = CGRectOffset(finalFrame,screenBounds.size.width,0)
        
        // 3. Add toVC's view to containerView
        let toView = toViewController!.view
        //toView.opaque = true
        //toView.alpha = 0.8
        containerView.addSubview(toView)
        
        //动画
        let duration = self.transitionDuration(transitionContext)
        UIView.animateWithDuration(duration,   // 动画时长
            delay : 0,
            usingSpringWithDamping : 0.8,  // 相似弹簧振动效果 0~1
            initialSpringVelocity : 0.2,   // 初始速度
            options : .CurveLinear,   // 动画过渡效果
            animations: {
                toViewController!.view.frame = finalFrame
            },
            completion: {(Bool finished) in
                transitionContext.completeTransition(true)
        })
        
    }
}

接下来是关闭的效果:测试

class NormalDismissAnimation: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval {
        return 0.4
    }
    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        // 1. Get controllers from transition context
        let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
        let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
        // 2. Set init frame for toVC
        let screenBounds = UIScreen.mainScreen().bounds
        let initFrame = transitionContext.finalFrameForViewController(fromViewController!)
        let finalFrame = CGRectOffset(initFrame, screenBounds.size.width, 0);
        let containerView = transitionContext.containerView()
        
        // 3. Add toVC's view to containerView
        containerView.addSubview(toViewController!.view)
        containerView.sendSubviewToBack(toViewController!.view)
        
        //动画
        let duration = self.transitionDuration(transitionContext)
        UIView.animateWithDuration(duration,
            animations: {
                fromViewController!.view.frame = finalFrame
            },
            completion: {(Bool finished) in
                transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
                if let window = UIApplication.sharedApplication().keyWindow {
                    if let viewController = window.rootViewController {
                        window.addSubview(toViewController!.view)
                    }
                }
        })
        
    }
    
}

主view中调用弹出函数:动画

func goModal(){
        var mVC = modalViewController()
        mVC.transitioningDelegate = self
        mVC.view.backgroundColor = UIColor.clearColor()
        mVC.modalPresentationStyle = .Custom
        self.presentViewController(mVC, animated: true, completion: nil)
       
    }

这里须要注意设置 mVC.view.backgroundColor = UIColor.clearColor()  后才能够在modal层中实现半透明.ui

还有一点是有个IOS8的bug,当弹出层收回时,主view会是黑屏.这里在DismissAnimation中,当completion: {(Bool finished) in 时 ,须要将toViewController.view加入到window中.spa

本例针对IOS8 版本测试code

引用地址:orm

UIViewController Initializers in Swift

相关文章
相关标签/搜索