web-dev-qa-db-ja.com

適応セグエでUITableViewにUIVisualEffectViewを実装する方法

UIVisualEffectViewを実装して、ビューにぼかし効果を適用し、その背後にあるビューを表示したいと思います。

背景をぼかす必要があるこのビューは、UITableViewControllerに埋め込まれたUINavigationControllerであり、iPadのポップオーバーで表示されるか、iPhoneでモーダルモードで表示されます。 iOS 8の適応型セグエ(Popoverとして提供)のおかげです。このView Controllerがポップオーバーにある場合、背景にPopoverの下にあるものをぼかし、フルスクリーンで表示する場合に背景に前のView Controllerをぼかします。

私はこれを実装しようとしましたが、成功していません。ポップオーバーでぼかし効果を働かせることさえできません。私はこのコードがトリックを行うべきだと思った:

//In viewDidLoad on the UITableViewController subclass:
let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
effectView.frame = tableView.frame
tableView.addSubview(effectView)

また、tableView.backgroundViewにサブビューを追加しようとしました。backgroundVieweffectViewに設定しようとしました。フレームを設定する代わりにAutolayout制約を使用しようとしましたが、何も機能しませんでした。希望する動作を達成するのを手伝ってもらえますか?

私が入手しようとしているものの例:
iPadポップオーバー:
enter image description here

iPhoneモーダルプレゼンテーション:
enter image description here

28
Jordan H

私は最終的に解決策を見つけました。私は2つの個別のセグエを作成する必要がありました。1つはiPadでのみ呼び出されるPopover Presentation用で、もう1つはiPhoneでPresentation StyleがOver Full Screen(重要)に設定されたモーダルセグエです。

表示されているTable View Controllerの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のトリックはbackgroundColorpopoverPresentationControllerを削除することでした。

47
Jordan H

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)
    }
  }
}
6
Yariv Nissim

これに少し遅れましたが、私にとって最適な解決策は(ios8 +で)、ストーリーボードでUIVisualEffectViewを取得し、それをViewControllerのルートビューにすることでした。次に、それにテーブルビューを追加します

enter image description here

視覚効果ビューを見つけるには、右下のコンポーネントピッカー(名前がわからない)に移動し、VisualEffectViewを検索します。

enter image description here

これは、これを実行するはるかに簡単な方法のように思われ、ストーリーボードで可能な限り多くの操作を行うというAppleの推奨事項に沿っています。

5
bolnad

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

    }
0
Jeremy Andrews