[英]UIBarButtonItem not decolorized/disabled when popover is on screen
我的導航控制器上有兩個UIBarButtonItems
:
segmentControl = UISegmentedControl(items: ["Up", "Down"])
infoItem = UIBarButtonItem(image: infoImage,
style: .plain,
target: self,
action: #selector(infoAction))
navigationItem.rightBarButtonItems = [infoItem, UIBarButtonItem(customView: segmentControl)]
當點擊infoItem
我做:
@objc func infoAction()
{
let popoverContentController = InfoViewController()
popoverContentController.preferredContentSize = CGSize(width: 300, height: 300)
popoverContentController.modalPresentationStyle = .popover
popoverContentController.popoverPresentationController?.delegate = self
popoverContentController.popoverPresentationController?.passthroughViews = nil
self.present(popoverContentController, animated: true, completion: nil)
}
然后調用UIPopoverPresentationControllerDelegate
函數:
func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController)
{
popoverPresentationController.permittedArrowDirections = .any
popoverPresentationController.barButtonItem = infoItem
popoverPresentationController.passthroughViews = nil
}
func adaptivePresentationStyle(for controller: UIPresentationController,
traitCollection: UITraitCollection) -> UIModalPresentationStyle
{
return .none
}
即使我將passthroughViews
設置為nil
兩次, UISegmentedControl
也不會脫色,並且在彈出窗口出現在屏幕上時仍然可以點擊。
如果顯示任何其他彈出框,則UISegmentedControl
行為正常:脫色且不可點擊。
我在這里缺少什么?
查看您的代碼,一切似乎都很好。 操作系統中似乎存在錯誤。
我找到了一個快速解決方案,除非他們在下一個 iOS 版本中檢查並修復它。
定義 barButtonItems 和一個變量以在 ViewController 中全局保存現有的色調顏色。
var infoItem: UIBarButtonItem! var segmentItem: UIBarButtonItem! var savedTintColour: UIColor? = nil
在你的ViewDidLoad()
初始化它們
segmentedControl = UISegmentedControl(items: ["Up", "Down"]) infoItem = UIBarButtonItem(image: UIImage(named: "setting_mobile"), style: .plain, target: self, action: #selector(infoAction)) segmentItem = UIBarButtonItem(customView: segmentedControl) navigationItem.rightBarButtonItems = [infoItem, segmentItem]
InfoAction 的代碼將保持不變。
@objc func infoAction() { let popoverContentController = InfoViewController() popoverContentController.preferredContentSize = CGSize(width: 300, height: 300) popoverContentController.modalPresentationStyle = .popover popoverContentController.popoverPresentationController?.delegate = self popoverContentController.popoverPresentationController?.passthroughViews = nil self.present(popoverContentController, animated: true, completion: nil) }
實現委托方法prepareForPopoverPresentation
並將色調顏色設置為 darkGray 並將之前可用的 tintColour 保存到一個變量中,以便我們可以在啟用時重用它。
func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) { popoverPresentationController.permittedArrowDirections = .any popoverPresentationController.barButtonItem = infoItem popoverPresentationController.passthroughViews = nil self.segmentItem.isEnabled = false if savedTintColour == nil { savedTintColour = self.segmentedControl.tintColor } self.segmentedControl.tintColor = .darkGray }
實現委托方法popoverPresentationControllerDidDismissPopover
,以重置popoverPresentationControllerDidDismissPopover
的顏色並啟用 segmentedItem。
func popoverPresentationControllerDidDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) { self.segmentItem.isEnabled = true self.segmentedControl.tintColor = savedTintColour! }
希望能幫助到你。
正如Bhavin Kansagara所說,模仿 iOS 行為是一種有效的解決方法。 他的回答很接近,但遺漏了一些細節:
popoverPresentationControllerDidDismissPopover
調用太晚導致分段控件在所有其他 UI 元素之后再次popoverPresentationControllerDidDismissPopover
藍色。 需要使用popoverPresentationControllerShouldDismissPopover
代替。segmentedControl
的isEnabled
也必須保存。這是我所做的,希望有更好的解決方案:
private var segmentedControlTintColor: UIColor?
private var segmentedControlIsEnabled: Bool = true
// Due to, what seems to be, an iOS issue, the segmented control is not decolorized when the info popover is
// on screen. The two functions below mimick iOS behavior until a better solution is found.
func decolorizeSegmentedControl()
{
segmentedControlIsEnabled = segmentedControl.isEnabled
segmentedControl.isEnabled = false
segmentedControlTintColor = segmentedControl.tintColor
UIView.animate(withDuration: 0.333)
{
self.segmentedControl.tintColor = self.segmentedControlIsEnabled ? .darkGray : .lightGray
}
}
func colorizeSegmentedControl()
{
segmentedControl.isEnabled = segmentedControlIsEnabled
UIView.animate(withDuration: 0.333)
{
self.segmentedControl.tintColor = self.segmentedControlTintColor
}
}
func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController)
{
popoverPresentationController.permittedArrowDirections = .any
popoverPresentationController.barButtonItem = infoItem
decolorizeSegmentedControl()
}
func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool
{
colorizeSegmentedControl()
return true
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.