Как реализовать UIVisualEffectView в UITableView с адаптивными сегментами
Я хотел бы реализовать UIVisualEffectView
, чтобы применить эффект размытия к представлению, чтобы показать представление, которое находится за ним.
Этот вид, который должен иметь размытый фон, представляет собой UITableViewController
, встроенный в UINavigationController
, и он будет либо представлен в popover на iPad, либо будет представлен полноэкранным образом на iPhone, благодаря iOS 8 адаптивных сегментов (присутствует как Popover). Когда этот диспетчер представлений находится в popover, я хочу, чтобы фон размыл то, что находится под popover, и когда он отображается в полноэкранном режиме, я хочу, чтобы фон размыл предыдущий контроллер представления.
Я попытался реализовать это и не добился успеха. Я даже не могу заставить эффект размытия работать для popover. Я думал, что этот код должен сделать трюк:
//In viewDidLoad on the UITableViewController subclass:
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
effectView.frame = tableView.frame
tableView.addSubview(effectView)
Я также попытался добавить subview к tableView.backgroundView
, я попробовал установить backgroundView
на мой effectView
, я пытался использовать ограничения Autolayout вместо установки фрейма, но ничего не сработало. Можете ли вы помочь мне выполнить желаемое поведение?
Пример того, что я пытаюсь получить:
iPad popover:
![enter image description here]()
iPhone модальная презентация:
![enter image description here]()
Ответы
Ответ 1
Наконец-то я нашел решение. Мне пришлось создать два отдельных сегмента: один для презентации Popover, который называется только на iPad, а другой - модальный сегмент с стилем презентации, установленным на Full Full Screen (что важно) для iPhone.
В представленном контроллере табличного представления в viewDidLoad
этот код применит желаемый эффект размытия (и бонус, только если они не отключили эффекты прозрачности):
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)
}
Это приводит к тому, что фон таблицы отображается так же, как на скриншотах. Трюк для iPhone заключался в том, чтобы обеспечить его отображение на экране, в то время как трюк для iPad заключался в том, чтобы удалить backgroundColor
в popoverPresentationController
.
Ответ 2
Быстрый пример добавления размытия с использованием адаптивности:
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)
}
}
}
Ответ 3
Немного поздно к столу с этим, но лучшим решением для меня (в ios8 +) было взятие UIVisualEffectView в Раскадке и сделать его корневым представлением моего ViewController. Затем добавьте мое представление в таблицу
![enter image description here]()
Чтобы найти визуальный эффект, перейдите в раздел "Выбор компонентов" (не уверен, что это вызвало) в нижней правой части и выполните поиск VisualEffectView
![enter image description here]()
Это похоже на гораздо более простой способ сделать это, и соответствует рекомендациям Apple, чтобы как можно больше сделать на раскадровке
Ответ 4
Небольшое изменение для 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
}