2017-05-01 12 views
0

ポップオーバーを表示しているとき、私はポップオーバーの外にあるすべてのビューが淡色表示になることを期待しています。 IB経由でポップオーバーを作成すると、これはうまく動作します。私がPopoverをプログラムで作成し、UIBarButtonItem経由で呼び出すと、これはうまくいきません。ナビゲーションバーのバックシェブロンは淡色表示されません。代わりに、それは青のまま:UINavigationBarのシェブロンがポップオーバーを表示しているときに淡色表示されない

enter image description here

コード:

class GreenViewController: UIViewController { 

    private var barButtonItem: UIBarButtonItem! 

    func barButtonItemAction() { 
     let blueViewController = BlueViewController() 
     let navigationController = UINavigationController(rootViewController: blueViewController) 
     navigationController.modalPresentationStyle = .popover 
     navigationController.popoverPresentationController?.barButtonItem = self.barButtonItem 
     self.present(navigationController, animated: true, completion: nil) 
    } 

    override func viewDidLoad() { 
     super.viewDidLoad() 

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

} 

これはなぜ起こるのでしょうか? Githubの上

テストプロジェクト: https://github.com/bvankuik/TestNavigationBarChevronTint/

答えて

1

私はpopovercontrollerはそれのアンカーとしてUIBarButtonItemを使用したときに何かがビュー階層にオフかもしれないと思います。 InterfaceBuilderでは、UIButtonは提示されたポップオーバーのアンカーであり、UIButtonはプレゼンテーションビューコントローラのビュー階層にあるため、うまくいくようです。

だから私は、次のようにpopoverPresentationControllersourceRectsourceViewプロパティを設定することにより、いくつかの類似した条件を再現しようと、それはトリックをしました。

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) 
    } 
} 

希望これは受賞:)

+0

バムを、役立ちます!驚くばかり!このことは、長い間私の嫌な思いをしていました。 –

+0

@BartvanKuikああああ、本当にあなたがどこから来ているのか理解している – AntonTheDev

関連する問題