简体   繁体   English

如何在UITableView中使用自适应segue实现UIVisualEffectView

[英]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). 这个应该让背景模糊的视图是一个嵌入在UINavigationControllerUITableViewController ,它将被呈现在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的伎俩是删除backgroundColorpopoverPresentationController

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM