ios – 呈现具有模糊效果的视图控制器

我正在以模糊背景效果模式呈现视图控制器. iOS 10 / XCode 8引入了我的动画问题.这是演示代码
let modalVC = ModalViewController(nibName: "ModalViewController",bundle: nil)
modalVC.modalTransitionStyle = .CrossDissolve
modalVC.modalPresentationStyle = .OverFullScreen
presentViewController(modalVC,animated: true,completion: nil)

在ModalViewController中的viewDidLoad()函数添加模糊:

let blurEffect = UIBlurEffect(style: .Light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
blurEffectView.autoresizingMask = [.FlexibleWidth,.FlexibleHeight]

view.addSubview(blurEffectView)
view.sendSubviewToBack(blurEffectView)

ModalViewController有一个清晰的背景,我添加了一个带有暗模糊效果的BlurEffectView.以编程方式使用上一个代码段和Interface Builder进行尝试.

在iOS 8& 9 .CrossDissolve过渡处理“淡入淡出”,但在iOS 10(设备和模拟器)上测试后,视图显示为深色半透明背景颜色而不是模糊.

.CrossDissolve动画完成后,背景颜色将更改为实际的模糊效果背景.任何想法为什么会这样?

还试图在viewDidLoad()的开头和结尾为模态视图控制器添加layoutIfNeeded(),没有任何运气.我正在使用swift 2.3

解决方法

嗨,

您需要创建一个新的UIViewControllerAnimatedTransitioning.

然后在animateTransition中(使用transitionContext:UIViewControllerContextTransitioning),您需要编写动画代码.

现在在iOS 10中,您可以使用UIViewPropertyAnimator为UIVisualBlurEffect的BlurRadius设置动画.

结果:

这里有一个用法示例:https://github.com/PierrePerrin/PPBlurModalPresentation

第一

您需要创建模糊转换

class BlurModalPresentation: NSObject,UIViewControllerAnimatedTransitioning {


        func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval{

            return 0.5
        }

//This is the blur view used for transition
        var blurView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.light))
        var destinationView : UIView!
        var animator: UIViewPropertyAnimator?

        // This method can only  be a nop if the transition is interactive and not a percentDriven interactive transition.
        func animateTransition(using transitionContext: UIViewControllerContextTransitioning){

            let containerView = transitionContext.containerView

            _ = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
            let toVc = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)

            destinationView = toVc!.view
            destinationView.alpha = 0.0

//Here we add the blur view and set it effect to nil
            blurView.effect = nil
            blurView.frame = containerView.bounds

            self.blurTransition(transitionContext) { 

                self.unBlur(transitionContext,completion: { 

                    self.blurView.removeFromSuperview()
                    transitionContext.completeTransition(true)
                })
            }

            containerView.addSubview(toVc!.view)
            containerView.addSubview(blurView)
        }

        //This methods add the blur to our view and our destinationView
        func blurTransition(_ context : UIViewControllerContextTransitioning,completion: @escaping () -> Void){

            UIViewPropertyAnimator.runningPropertyAnimator(withDuration: self.transitionDuration(using: context)/2,delay: 0,options: UIViewAnimationOptions.curveLinear,animations: {

                self.destinationView.alpha = 0.5
                  self.blurView.effect = UIBlurEffect(style: UIBlurEffectStyle.light)
            },completion: { (position) in
                completion()
            })

        }
        //This Method remove the blur view with an animation
        func unBlur(_ context : UIViewControllerContextTransitioning,completion: @escaping () -> Void){

            UIViewPropertyAnimator.runningPropertyAnimator(withDuration: self.transitionDuration(using: context) / 2,delay:0,animations: {

                self.destinationView.alpha = 1.0
                self.blurView.effect = nil
            },completion: { (position) in
                completion()
            })
        }

    }

然后

您需要在ViewController中设置转换委派:

import UIKit

class ViewController: UIViewController,UIViewControllerTransitioningDelegate {

    let blurModalPresentation = BlurModalPresentation()

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    func showVC(){

        let str = self.storyboard!
        let vc = str.instantiateViewController(withIdentifier: "YourViewControllerIdentifier")
        vc.transitioningDelegate = self
        self.present(vc,completion: nil)
    }


    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    }

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

        return blurModalPresentation
    }


    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning?{

        return blurModalPresentation
    }

}

相关文章

背景 前端时间产品经理决定使用百度统计,使得 工程B 中原统计sdk-友盟统计,需要被去除。之前尝试去除...
结论: alloc负责分配内存和创建对象对应的isa指针; init只是返回alloc生成的对象。 所以alloc后,多次...
更新 如果UI愿意把启动图切割成n份,按一定约束在launchscreen.storyboard中进行排版,启动图效果会更好...
最近在看一本书《Effective OC 2.0》,今天看到有个tip是OC适中循环各自优劣性,作者最终推荐此块循环。...
// // ViewController.m // paintCodeTestOC //gif // Created by LongMa on 2019/7/25. // #import &a...
背景介绍 一般情况下,出于省电、权限、合理性等因素考虑,给人的感觉是很多奇怪的需求安卓可以实现,但...