Je voudrais implémenter UIVisualEffectView
pour appliquer un effet de flou à une vue afin de montrer la vue qui la sous-tend.
Cette vue qui devrait avoir un arrière-plan flou est une UITableViewController
intégrée à une UINavigationController
. Elle sera présentée dans une fenêtre popover sur iPad ou sera présentée en mode plein écran sur iPhone, grâce à iOS 8 adaptations ). Lorsque ce contrôleur de vue est affiché dans un popover, je souhaite que l'arrière-plan brouille ce qui se trouve sous celui-ci. Lorsqu'il est affiché en plein écran, je souhaite que l'arrière-plan brouille le contrôleur de vue précédent.
J'ai essayé de mettre cela en œuvre et je n'ai pas réussi. Je n'arrive même pas à obtenir l'effet de flou pour le popover. J'ai pensé que ce code devrait faire l'affaire:
//In viewDidLoad on the UITableViewController subclass:
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
effectView.frame = tableView.frame
tableView.addSubview(effectView)
J'ai également essayé d'ajouter la sous-vue au tableView.backgroundView
, j'ai essayé de définir la backgroundView
sur ma effectView
, j'ai essayé d'utiliser des contraintes Autolayout au lieu de définir le cadre, mais rien n'a fonctionné. Pouvez-vous m'aider à accomplir le comportement souhaité?
Un exemple de ce que je cherche à obtenir:
Popover iPad:
présentation modale iPhone:
J'ai enfin trouvé une solution. J'ai dû créer deux séquences distinctes - une pour une présentation Popover appelée uniquement sur iPad et l'autre, une séquence modale avec Style de présentation défini sur Plein écran (c'est important) pour iPhone.
Dans le contrôleur de vue de table présenté, dans viewDidLoad
, ce code appliquera l'effet de flou souhaité (et le bonus, uniquement s'ils n'ont pas désactivé les effets de transparence):
if (!UIAccessibilityIsReduceTransparencyEnabled()) {
tableView.backgroundColor = UIColor.clear
let blurEffect = UIBlurEffect(style: .light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
tableView.backgroundView = blurEffectView
//if inside a popover
if let popover = navigationController?.popoverPresentationController {
popover.backgroundColor = UIColor.clear
}
//if you want translucent vibrant table view separator lines
tableView.separatorEffect = UIVibrancyEffect(blurEffect: blurEffect)
}
Cela provoque l’arrière-plan du tableau comme dans les captures d’écran. Pour iPhone, l’astuce consistait à s’assurer qu’elle était présentée à l’écran, tandis que pour iPad, il fallait supprimer backgroundColor
dans popoverPresentationController
.
Un exemple rapide pour ajouter le flou en utilisant Adaptivity:
extension ViewController: UIPopoverPresentationControllerDelegate {
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Grab the destination view controller and set the presentation delegate
let viewController = segue.destinationViewController as UIViewController
viewController.popoverPresentationController?.delegate = self
viewController.presentationController?.delegate = self
}
// Note: Only called for FormSheet and Popover
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
switch controller.presentedViewController {
case let vc as PopoverViewController:
return .None // Keep the popover in Compact screens
default:
return .OverFullScreen
}
}
func presentationController(controller: UIPresentationController, viewControllerForAdaptivePresentationStyle style: UIModalPresentationStyle) -> UIViewController? {
// This is a custom method on UIViewController
controller.presentedViewController.createBlur()
// Wrap in a Navigation Controller, the controller should add a title and bar buttons
if !(presentedViewController is UINavigationController) {
return UINavigationController(rootViewController: presentedViewController)
}
}
}
extension UIViewController {
func createBlur(effectStyle: UIBlurEffectStyle = .Light) {
if !UIAccessibilityIsReduceTransparencyEnabled() {
view.backgroundColor = UIColor.clearColor()
let blurView = UIVisualEffectView(effect: UIBlurEffect(style: effectStyle))
blurView.autoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth
blurView.frame = view.bounds
view.insertSubview(blurView, atIndex: 0)
}
}
}
extension UITableViewController {
override func createBlur(effectStyle: UIBlurEffectStyle = defaultBlurEffectStyle) {
if !UIAccessibilityIsReduceTransparencyEnabled() {
tableView.backgroundColor = UIColor.clearColor()
let blurEffect = UIBlurEffect(style: effectStyle)
tableView.backgroundView = UIVisualEffectView(effect: blurEffect)
tableView.separatorEffect = UIVibrancyEffect(forBlurEffect: blurEffect)
}
}
}
Un peu tard pour la table avec celui-ci, mais la meilleure solution pour moi (sous ios8 +) était de prendre un UIVisualEffectView dans le Storyboard et d'en faire la vue racine de mon ViewController. Ajoutez ensuite ma tableview à celle
Pour trouver la vue des effets visuels, allez dans le sélecteur de composants (vous ne savez pas comment on l'appelle) en bas à droite et recherchez VisualEffectView.
Cela semble être un moyen beaucoup plus facile de s'y prendre et s'inscrit dans la recommandation d'Apple de faire autant que possible sur le Storyboard.
Un petit changement pour IOS 10 Swift 3
if #available(iOS 10.0, *) {
let blurEffect = UIBlurEffect(style: .prominent)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
groupTable.backgroundView = blurEffectView
} else {
let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
groupTable.backgroundView = blurEffectView
}