[英]Presenting View Controller with Blur Effect
我正在以模糊背景效果模式呈現視圖控制器。 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(using transitionContext: UIViewControllerContextTransitioning)
您需要編寫動畫代碼。
現在,在iOS 10中,您可以使用UIViewPropertyAnimator
為BlurRadius
的UIVisualBlurEffect
設置動畫。
這里有一個用法示例: 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, 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 } }
首先,我將此解決方案視為臨時解決方法,因為我必須假設這個新引入的行為是一個錯誤,並將在未來的更新中修復。 這使得它在動畫期間而不是之后彈出模糊效果時略顯不太明顯。 仍然沒有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 } }
唯一正確的方法是創建自定義模態轉換和動畫效果屬性。 請參閱https://stackoverflow.com/a/39709740
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.