显示弹出窗口时,UINavigationBar中的雪佛龙不会变暗

时间:2017-05-01 07:39:07

标签: ios swift ipad uinavigationcontroller uinavigationbar

当我显示一个弹出窗口时,我希望弹出窗口外的所有视图都会变暗。当我通过IB创建一个popover时,这很好用。当我以编程方式创建一个弹出窗口并通过UIBarButtonItem调用它时,这不太有效:导航栏中的后面V形图形不会变暗。相反,它仍然是蓝色的:

enter image description here

代码:

AsyncRestTemplate

为什么会这样?

Github上的测试项目: https://github.com/bvankuik/TestNavigationBarChevronTint/

1 个答案:

答案 0 :(得分:1)

我认为当popovercontroller使用UIBarButtonItem作为锚点时,视图层次结构中可能会出现问题。在InterfaceBuilder中,UIButton是呈现的弹出窗口的锚点,并且由于UIButton位于呈现视图控制器的视图层次结构中,因此似乎正常工作。

所以我尝试通过在sourceRect上设置sourceViewpopoverPresentationController属性来重现一些类似的条件,如下所示,它就可以了。

class GreenViewController: UIViewController, UIPopoverPresentationControllerDelegate {

    private var barButtonItem: UIBarButtonItem!

    override func viewDidLoad() {
        super.viewDidLoad()
        barButtonItem = UIBarButtonItem(title: "Show blue popover", style: .plain,
                                        target: self,  action: #selector(barButtonItemAction))
        navigationItem.rightBarButtonItem = barButtonItem
    }


    // Defined constants for solution readability

    private let sourceRectHeight         : CGFloat = 44.0   // NavigationBar Height?
    private let sourceRectWidth          : CGFloat = 160.0  // UIBarButtonItem Width?
    private let sourceRectRightMargin    : CGFloat = 20.0   // Right Margin


    // This returns the source rect to align our popoverPresentationController
    // against, this is pretty much my imaginary frame of the UIBarButtonItem

    private var sourceRect : CGRect
    {
        var rect = navigationController!.navigationBar.frame
        rect.origin.x = view.bounds.width - sourceRectWidth - sourceRectRightMargin
        rect.origin.y = sourceRectHeight / 2.0
        rect.size.width = sourceRectWidth
        return rect
    }

    func barButtonItemAction() {

        let blueViewController = BlueViewController()
        let navigationController = UINavigationController(rootViewController: blueViewController)
        navigationController.modalPresentationStyle = .popover

        // Instead of setting the barButtonItem on the popoverPresentationController
        // set the srouce view as the root view of the presenting controller

        navigationController.popoverPresentationController?.sourceView = view

        // Set the source rec to present from, which is calclated relative to the width
        // of the current device orientation

        navigationController.popoverPresentationController?.sourceRect = sourceRect

        // Set self as the delegate for the popoverPresentationController because
        // we need to provide a relaculated rect when the device changes orientation

        navigationController.popoverPresentationController?.delegate = self

        // Present the view controller, and voila :)

        self.present(navigationController, animated: true, completion: nil)
    }


    // UIPopoverPresentationControllerDelegate method that allows us to update 
    // the source rect of the popover after an orientation change has occurred,
    // which calculated relative to with in the sourceRect property above

    public func popoverPresentationController(_ popoverPresentationController: UIPopoverPresentationController,
                                              willRepositionPopoverTo rect: UnsafeMutablePointer<CGRect>,
                                              in view: AutoreleasingUnsafeMutablePointer<UIView>)
    {
        rect.initialize(to: sourceRect)
    }
}

希望这会有所帮助:)