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

后端 未结 6 1981
南笙
南笙 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: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.

提交回复
热议问题