当我显示一个弹出窗口时,我希望弹出窗口外的所有视图都会变暗。当我通过IB创建一个popover时,这很好用。当我以编程方式创建一个弹出窗口并通过UIBarButtonItem调用它时,这不太有效:导航栏中的后面V形图形不会变暗。相反,它仍然是蓝色的:
代码:
AsyncRestTemplate
为什么会这样?
Github上的测试项目: https://github.com/bvankuik/TestNavigationBarChevronTint/
答案 0 :(得分:1)
我认为当popovercontroller使用UIBarButtonItem作为锚点时,视图层次结构中可能会出现问题。在InterfaceBuilder中,UIButton是呈现的弹出窗口的锚点,并且由于UIButton位于呈现视图控制器的视图层次结构中,因此似乎正常工作。
所以我尝试通过在sourceRect
上设置sourceView
和popoverPresentationController
属性来重现一些类似的条件,如下所示,它就可以了。
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)
}
}
希望这会有所帮助:)