Ios 显示具有模糊效果的视图控制器

Ios 显示具有模糊效果的视图控制器,ios,iphone,swift,xcode8,uiblureffect,Ios,Iphone,Swift,Xcode8,Uiblureffect,我正在演示一个带有模糊背景效果的视图控制器。iOS 10/XCode 8导致我的动画出现问题。这是演示代码: let modalVC = ModalViewController(nibName: "ModalViewController", bundle: nil) modalVC.modalTransitionStyle = .CrossDissolve modalVC.modalPresentationStyle = .OverFullScreen presentViewController

我正在演示一个带有模糊背景效果的视图控制器。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和iOS 9上,
.crosssolve
转换处理了“褪色”,但在iOS 10(设备和模拟器)上测试后,视图显示为深色半透明背景色,而不是模糊

.crosssolve
动画完成后,背景颜色将更改为实际的模糊效果背景。知道为什么会这样吗


还尝试在模式视图控制器的
viewDidLoad()
的开头和结尾添加
layoutifneed()
。我使用的是swift 2.3,首先,我将此解决方案视为临时解决方案,因为我必须假设此新引入的行为是一个bug,将在将来的更新中修复。这会使模糊效果在动画期间而不是之后突然出现时,变得不那么明显。仍然没有iOS 9和向后版本那么好,但是稍微好一点

  • 显示不带动画的视图控制器:

    presentViewController(modalVC, animated: false, completion: nil)
    
  • 从一开始就隐藏视图:

    override func viewDidLoad() {
        super.viewDidLoad()
    
        view.alpha = 0
    }
    
  • 手动应用动画:

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
    
        UIView.animateWithDuration(0.25) {
            self.view.alpha = 1
        }
    }
    
    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
    
        UIView.animateWithDuration(0.25) {
            self.view.alpha = 0
        }
    }
    

  • 唯一正确的方法是创建自定义模态转换和动画效果属性。见

    嗨, 您需要创建一个新的
    UIViewControllerAnimatedTransitioning

    然后在
    animateTransition(使用transitionContext:UIViewControllerContextTransitioning)
    中,您需要对动画进行编码

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

    结果:

    这里有一个用法示例:

    弗斯特 您需要创建模糊过渡

        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, options: UIViewAnimationOptions.curveLinear, 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, animated: true, 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
        }
    
    }
    

    我也发现了这种令人讨厌的行为变化。您是否尝试过关闭过渡样式并手动处理动画?尝试过后,效果会更好,但模糊仍有轻微延迟。只是不那么引人注目,有一个可访问性功能,它可以禁用模糊,供忘记这一点的人使用。同样+1表示OP,我也有同样的问题。我有一个表格视图,在显示的VC后面有自定义单元格。模糊只适用于交叉溶解动画结束时后面的东西,然后突然模糊了呈现的VC。是的,这似乎是目前唯一的解决办法,但额外的延迟有点烦人。在接受之前,我会把这个问题留一段时间,希望有人能想出一个替代的解决方案。我理解你的观点,但你可能想将步骤1编辑为
    presentViewController(modalVC,动画:false,完成:nil)
    Oops,谢谢@Fdo!将
    动画
    更改为
    。我不希望把这个答案选作解决方案,因为它远非完美无缺。也希望有人能想出更好的办法!