How can I change the opacity of the overlay behind UIPopoverPresentationController?

后端 未结 6 1980
南笙
南笙 2021-01-12 19:28

I\'m using UIPopoverPresentationController to present popovers in an iOS app. I want to dim the background behind the popover when it comes up. How can I do thi

相关标签:
6条回答
  • 2021-01-12 19:30
    popoverController.contentViewController.view.alpha = 0.5;
    

    Transparent UIPopover

    0 讨论(0)
  • 2021-01-12 19:34

    A drop-in non-intrusive solution: showing/hiding up an overlay view via UIPopoverPresentationControllerDelegate, like this: (in Swift 2.0)

    class PopoverDelegate: NSObject, UIPopoverPresentationControllerDelegate {
        var overlay: UIView?
    
        dynamic func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle {
            return .None
        }
    
        dynamic func presentationController(presentationController: UIPresentationController, willPresentWithAdaptiveStyle style: UIModalPresentationStyle, transitionCoordinator: UIViewControllerTransitionCoordinator?) {
            // add a semi-transparent view to parent view when presenting the popover
            let parentView = presentationController.presentingViewController.view
    
            let overlay = UIView(frame: parentView.bounds)
            overlay.backgroundColor = UIColor(white: 0.0, alpha: 0.4)
            parentView.addSubview(overlay)
    
            let views: [String: UIView] = ["parentView": parentView, "overlay": overlay]
    
            parentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[overlay]|", options: [], metrics: nil, views: views))
            parentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[overlay]|", options: [], metrics: nil, views: views))
    
            overlay.alpha = 0.0
    
            transitionCoordinator?.animateAlongsideTransition({ _ in
                overlay.alpha = 1.0
            }, completion: nil)
    
            self.overlay = overlay
        }
    
        deinit {
            // remove the overlay with animation.
            // the delegate method popoverPresentationControllerDidDismissPopover(_:) is not called 
            // if the popover is dismissed programmatically, 
            // so the removal goes here.
    
            guard let overlay = overlay else {
                return
            }
            dispatch_async(dispatch_get_main_queue()) {
                UIView.animateWithDuration(0.2, animations: {
                    overlay.alpha = 0.0
                    }, completion: { _ in
                        overlay.removeFromSuperview()
                })
            }
        }
    
    }
    

    Then when a popver is about to be presented, set the delegate of UIPopoverPresentationController to an instance of PopoverDelegate, and you get a dimmed background behind the popover.

    0 讨论(0)
  • 2021-01-12 19:36

    in swift 3 you can access the overlay:

    extension UIPopoverPresentationController {
    
        var dimmingView: UIView? {
           return value(forKey: "_dimmingView") as? UIView
        }
    }
    

    After setting your controller to popover mode

    controller.modalPresentationStyle = UIModalPresentationStyle.popover
    controller.popoverPresentationController.dimmingView.backgroundColor = UIColor.black.withAlphaComponent(0.4)
    
    0 讨论(0)
  • 2021-01-12 19:39

    Present via UIPopoverPresentationController and use its delegate method to change the containerView attributes:

    - (void)prepareForPopoverPresentation:(UIPopoverPresentationController *)popoverPresentationController {
    //
    popoverPresentationController.containerView.backgroundColor = [UIColor colorWithWhite:0 alpha:.72];
    
    0 讨论(0)
  • 2021-01-12 19:45

    I ended up solving this by putting my own overlay over my main view when I present the popover. I was able to do this easily because I do all my popovers through one singleton coordinator class, my root view controller isn't a navigation controller, and I can get to it easily everywhere. I also had to create a subclass of UINavigationController everywhere I presented one in a popover so I could override dismissViewControllerAnimated:completion: and notify the coordinator so it removed the overlay (the didDismiss delegate method doesn't get called when the popover is dismissed programmatically).

    0 讨论(0)
  • 2021-01-12 19:52

    I just created my view controller, set the popover style and then presented it, setting the background color in the completion callback (because the containerView will be non-nil at that point). Works well with Swift 4+.

    let myViewController: MyViewController = MyViewController()
    myViewController.modalPresentationStyle = UIModalPresentationStyle.popover
    
    if let presentationController: UIPopoverPresentationController = myViewController.popoverPresentationController {
        presentationController.delegate = self.mainViewController
        presentationController.sourceView = sourceView
        presentationController.sourceRect = sourceRect
        self.mainViewController.present(myViewController, animated: false, completion: {
            presentationController.containerView?.backgroundColor = UIColor.white.withAlphaComponent(0.5)
        })
    }
    
    0 讨论(0)
提交回复
热议问题