[英]How to implement UIVisualEffectView in UITableView with adaptive segues
I would like to implement UIVisualEffectView
to apply a blur effect to a view to show the view that lies behind it. 我想实现
UIVisualEffectView
以将模糊效果应用于视图以显示其背后的视图。
This view that should have its background blurred is a UITableViewController
that is embedded in a UINavigationController
, and it will either be presented in a popover on iPad or it will be presented full screen modally on iPhone, thanks to iOS 8 adaptive segues (Present as Popover). 这个应该让背景模糊的视图是一个嵌入在
UINavigationController
的UITableViewController
,它将被呈现在iPad上的popover中,或者它将在iPhone上以模式全屏显示,这要归功于iOS 8自适应segues(作为Popover呈现) )。 When this view controller is in a popover I want the background to blur what's underneath the popover, and when it's presented full screen I want the background to blur the previous view controller. 当这个视图控制器在弹出框中时,我希望背景模糊弹出框下面的内容,当它全屏显示时,我希望背景模糊前一个视图控制器。
I have tried to implement this and have not been successful. 我试图实现这个并且没有成功。 I cannot even get the blur effect to work for the popover.
我甚至无法使模糊效果适用于弹出窗口。 I thought this code should do the trick:
我认为这段代码可以解决问题:
//In viewDidLoad on the UITableViewController subclass:
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
effectView.frame = tableView.frame
tableView.addSubview(effectView)
I also tried adding the subview to the tableView.backgroundView
, I tried setting the backgroundView
to my effectView
, I tried using Autolayout constraints instead of setting the frame, but nothing has worked. 我也尝试将子视图添加到
tableView.backgroundView
,我尝试将backgroundView
设置为我的effectView
,我尝试使用Autolayout约束而不是设置框架,但没有任何工作。 Can you help me accomplish the desired behavior? 你能帮助我完成所期望的行为吗?
An example of what I am trying to obtain: 我想要获得的一个例子:
iPad popover: iPad popover:
iPhone modal presentation: iPhone模态演示:
I've finally found a solution. 我终于找到了解决方案。 I had to create two separate segues - one for a Popover Presentation which is called only on iPad, and the other a modal segue with Presentation Style set to Over Full Screen (that's important) for iPhone.
我不得不创建两个单独的segue - 一个用于仅在iPad上调用的Popover Presentation,另一个用于iPhone的Presentation Style设置为Over Full Screen(这很重要)的模式segue。
In the table view controller that is being presented, in viewDidLoad
, this code will apply the desired blur effect (and bonus, only if they haven't disabled transparency effects): 在正在显示的表视图控制器中,在
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)
}
This causes the table background to appear just like it does in the screenshots. 这会导致表背景显示就像在屏幕截图中一样。 The trick for iPhone was to ensure it's presented over the screen, while the trick for iPad was to remove the
backgroundColor
in the popoverPresentationController
. 为iPhone诀窍是确保它呈现在屏幕上,同时适用于iPad的伎俩是删除
backgroundColor
在popoverPresentationController
。
A quick example to add the blur using Adaptivity: 使用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)
}
}
}
Slightly late to the table with this one, but the best solution for me (in ios8 +), was to take a UIVisualEffectView in the Storyboard and make it the root view of my ViewController. 使用这个有点晚了,但对我来说最好的解决方案(在ios8 +中)是在Storyboard中使用UIVisualEffectView并使其成为我的ViewController的根视图。 Then add my tableview to that
然后将我的tableview添加到那里
To find the Visual Effect View, go to the Components Picker (not sure what thats called) on the bottom right hand side and search for VisualEffectView 要查找视觉效果视图,请转到右下角的组件选择器(不确定那些名称)并搜索VisualEffectView
This seems like a much easier way to go about it, and falls in line with Apple's recommendation to do as much on the Storyboard as possible 这似乎是一种更容易实现的方式,并且符合Apple的建议,即尽可能多地在Storyboard上进行操作
A small change for IOS 10 Swift 3 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
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.