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

主Viewcontroller 需要使用UIViewControllerTransitioningDelegate协议:

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也是个难题: 

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层中实现半透明.

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

本例针对IOS8 版本测试

引用地址:

UIViewController Initializers in Swift

 

转载于:https://www.cnblogs.com/ericjun/p/4304947.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值