【问题标题】:How to display a PopoverViewController from a custom Navigation Bar Right Button?如何从自定义导航栏右按钮显示 Popover ViewController?
【发布时间】:2019-08-05 18:37:16
【问题描述】:

我创建了一个自定义导航栏类​​,如下图所示,我在多个 ViewController 中使用它:

import UIKit

import ChameleonFramework

class CustomUINavigationBar: UINavigationBar {

    let navigationBarRightButtonView = UIView()

    override init(frame: CGRect) {

        super.init(frame: frame)

    }

    required init?(coder aDecoder: NSCoder) {

        super.init(coder: aDecoder)

    }

    convenience init(rightNavBarButtonTitleForNormalState: String, rightNavBarButtonImageForNormalState: String, rightNavBarButtonImageForHighlightedState: String, rightNavBarButtonTarget: Any?, rightNavBarButtonSelector: Selector, isNavBarTranslucent: Bool, navBarBackgroundColourHexCode: String, navBarBackgroundColourAlphaValue: CGFloat, navBarStyle: UIBarStyle, preferLargeTitles: Bool, navBarDelegate: UINavigationBarDelegate, navBarItemsHexColourCode: String, normalStateNavBarLeftButtonImage: String, highlightedStateNavBarLeftButtonImage: String, navBarLeftButtonTarget: Any?, navBarLeftButtonSelector: Selector, labelTitleText: String, titleLabelFontHexColourCode: String, labelTitleFontSize: CGFloat, labelTitleFontType: String) {

        self.init()

        addNavBarRightButton(rightNavBarButtonTitleForNormalState: rightNavBarButtonTitleForNormalState, rightNavBarButtonImageForNormalState: rightNavBarButtonImageForNormalState, rightNavBarButtonImageForHighlightedState: rightNavBarButtonImageForHighlightedState, rightNavBarButtonTarget: rightNavBarButtonTarget, rightNavBarButtonSelector: rightNavBarButtonSelector)

        addNavBarLeftButton(normalStateNavBarLeftButtonImage: normalStateNavBarLeftButtonImage, highlightedStateNavBarLeftButtonImage: highlightedStateNavBarLeftButtonImage, navBarLeftButtonTarget: navBarLeftButtonTarget, navBarLeftButtonSelector: navBarLeftButtonSelector)

        setupNavigationBarEssentials(isNavBarTranslucent: isNavBarTranslucent, navBarBackgroundColourHexCode: navBarBackgroundColourHexCode, navBarBackgroundColourAlphaValue: navBarBackgroundColourAlphaValue, navBarStyle: navBarStyle, preferLargeTitles: preferLargeTitles, navBarDelegate: navBarDelegate, navBarItemsHexColourCode: navBarItemsHexColourCode)

        addTitleLabel(labelTitleText: labelTitleText, titleLabelFontHexColourCode: titleLabelFontHexColourCode, labelTitleFontSize: labelTitleFontSize, labelTitleFontType: labelTitleFontType)

    }

    let customNavigationBarItem = UINavigationItem()

    func addTitleLabel(labelTitleText titleText: String, titleLabelFontHexColourCode hexCode: String, labelTitleFontSize fontSize: CGFloat, labelTitleFontType fontType: String) {

        let navBarTitle = UILabel(frame: CGRect(x: 0, y: 0, width: frame.width, height: 44))

        navBarTitle.text = titleText

        navBarTitle.textColor = UIColor(hexString: hexCode)

        navBarTitle.textAlignment = .center

        navBarTitle.font = UIFont(name: fontType, size: fontSize)

        navBarTitle.numberOfLines = 0

        navBarTitle.lineBreakMode = .byWordWrapping

        customNavigationBarItem.titleView = navBarTitle

    }

    func addNavBarLeftButton(normalStateNavBarLeftButtonImage: String, highlightedStateNavBarLeftButtonImage: String, navBarLeftButtonTarget: Any?, navBarLeftButtonSelector: Selector) {

        let navBarLeftButton: UIButton = {

            let button = UIButton()

            let normalStateNavBarLeftButtonImage = UIImage(named: normalStateNavBarLeftButtonImage)

            let highlightedStateNavBarLeftButtonImage = UIImage(named: highlightedStateNavBarLeftButtonImage)

            button.setImage(normalStateNavBarLeftButtonImage, for: .normal)

            button.setImage(highlightedStateNavBarLeftButtonImage, for: .highlighted)

            button.addTarget(navBarLeftButtonTarget, action: navBarLeftButtonSelector, for: .touchUpInside)

            button.translatesAutoresizingMaskIntoConstraints = false

            return button
        }()

        let navBarLeftView: UIView = {

            let view = UIView()

            view.addSubview(navBarLeftButton)

            NSLayoutConstraint.activate([

                navBarLeftButton.topAnchor.constraint(equalTo: view.topAnchor),

                navBarLeftButton.rightAnchor.constraint(equalTo: view.rightAnchor),

                navBarLeftButton.bottomAnchor.constraint(equalTo: view.bottomAnchor),

                navBarLeftButton.leftAnchor.constraint(equalTo: view.leftAnchor)

                ])

            return view

        }()

        let navBarLeftButtonItem = UIBarButtonItem(customView: navBarLeftView)

        customNavigationBarItem.leftBarButtonItem = navBarLeftButtonItem

    }

    func addNavBarRightButton(rightNavBarButtonTitleForNormalState: String, rightNavBarButtonImageForNormalState: String, rightNavBarButtonImageForHighlightedState: String, rightNavBarButtonTarget: Any?, rightNavBarButtonSelector: Selector) {
        rightNavigationBarDropDownButton.setTitle(rightNavBarButtonTitleForNormalState, for: .normal)

        rightNavigationBarDropDownButton.setImage(UIImage(named: rightNavBarButtonImageForNormalState), for: .normal)

        rightNavigationBarDropDownButton.setTitleColor(.black, for: .normal)

        rightNavigationBarDropDownButton.setTitleColor(.blue, for: .highlighted)

        rightNavigationBarDropDownButton.addTarget(rightNavBarButtonTarget, action: rightNavBarButtonSelector, for: .touchUpInside)

        rightNavigationBarDropDownButton.translatesAutoresizingMaskIntoConstraints = false

        navigationBarRightButtonView.addSubview(rightNavigationBarDropDownButton)


        NSLayoutConstraint.activate([

            rightNavigationBarDropDownButton.topAnchor.constraint(equalTo: navigationBarRightButtonView.topAnchor),

            rightNavigationBarDropDownButton.rightAnchor.constraint(equalTo: navigationBarRightButtonView.rightAnchor),

            rightNavigationBarDropDownButton.leftAnchor.constraint(equalTo: navigationBarRightButtonView.leftAnchor),

            rightNavigationBarDropDownButton.bottomAnchor.constraint(equalTo: navigationBarRightButtonView.bottomAnchor)

            ])

        let navigationBarRightViewitem = UIBarButtonItem(customView: navigationBarRightButtonView)

        customNavigationBarItem.rightBarButtonItem = navigationBarRightViewitem

    }

    func setupNavigationBarEssentials(isNavBarTranslucent: Bool, navBarBackgroundColourHexCode: String, navBarBackgroundColourAlphaValue: CGFloat, navBarStyle: UIBarStyle, preferLargeTitles: Bool, navBarDelegate: UINavigationBarDelegate, navBarItemsHexColourCode: String) {

        items = [customNavigationBarItem]

        isTranslucent = isNavBarTranslucent

        barTintColor = UIColor(hexString: navBarBackgroundColourHexCode, withAlpha: navBarBackgroundColourAlphaValue)

        barStyle = navBarStyle

        prefersLargeTitles = preferLargeTitles

        delegate = navBarDelegate

        tintColor = UIColor(hexString: navBarItemsHexColourCode)

        translatesAutoresizingMaskIntoConstraints = false

    }

}

然后,我从上面的自定义导航栏类​​创建了一个实例到我希望自定义导航栏显示的 viewController 中。然后我尝试在用户点击 NavBarRightButtonItem 时显示 PopoverViewController,但是没有任何显示,请有人帮我弄清楚我哪里出错了,非常感谢?

import UIKit

class BlueBookUniversalBeamsVC: UIViewController, UINavigationBarDelegate, UIPopoverPresentationControllerDelegate {

    lazy var navigationBar = CustomUINavigationBar(rightNavBarButtonTitleForNormalState: "Sort By:", rightNavBarButtonImageForNormalState: "pullDownButton", rightNavBarButtonImageForHighlightedState: "pullUpButton", rightNavBarButtonTarget: self, rightNavBarButtonSelector: #selector(navigationBarRightButtonPressed(sender:)), isNavBarTranslucent: false, navBarBackgroundColourHexCode: "#FFFFFF", navBarBackgroundColourAlphaValue: 1.0, navBarStyle: .black, preferLargeTitles: false, navBarDelegate: self, navBarItemsHexColourCode: "#FF4F40", normalStateNavBarLeftButtonImage: "normalStateBackButton", highlightedStateNavBarLeftButtonImage: "highlightedStateBackButton", navBarLeftButtonTarget: self, navBarLeftButtonSelector: #selector(navigationBarLeftButtonPressed(sender:)), labelTitleText: "Universal Beams (UB)", titleLabelFontHexColourCode: "#000000", labelTitleFontSize: 16, labelTitleFontType: "AppleSDGothicNeo-Light")

    override func viewDidLoad() {

        super.viewDidLoad()

        view.addSubview(navigationBar)

        }

    }

    override func viewDidLayoutSubviews() {

        setupConstraints()

    }

    @objc func navigationBarLeftButtonPressed(sender : UIButton) {

        let viewControllerToGoTo = BlueBookTabController()

        present(viewControllerToGoTo, animated: true, completion: nil)

    }

    @objc func navigationBarRightButtonPressed(sender : UIButton) {

        let button = sender as? UIButton

        let buttonFrame = button?.frame ?? CGRect.zero

        let popoverContentController = self.storyboard?.instantiateViewController(withIdentifier: "PopoverViewController") as? PopoverViewController

        popoverContentController?.modalPresentationStyle = .popover

        if let popoverPresentationController = popoverContentController?.popoverPresentationController {

            popoverPresentationController.permittedArrowDirections = .up

            popoverPresentationController.sourceView = self.view

            popoverPresentationController.sourceRect = buttonFrame

            popoverPresentationController.delegate = self

            if let popoverController = popoverContentController {

                present(popoverController, animated: true, completion: nil)

            }

        }

    }

    func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {

        return .none

    }

    func popoverPresentationControllerDidDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) {

    }

    func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool {

        return true

    }

    func position(for bar: UIBarPositioning) -> UIBarPosition {

        return UIBarPosition.topAttached

    }

    func setupConstraints() {

        NSLayoutConstraint.activate([

            navigationBar.leftAnchor.constraint(equalTo: view.leftAnchor),

            navigationBar.rightAnchor.constraint(equalTo: view.rightAnchor),

            navigationBar.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),

            ])

    }

}

【问题讨论】:

    标签: swift xcode uibarbuttonitem uipopovercontroller navigationbar


    【解决方案1】:

    我设法使用下面的代码解决了我的问题,一开始让我感到困惑的是我使用的是独立的 NavigationBar 而不是 NavigationBar 控制器:

    @objc func navigationBarRightButtonPressed(sender : UIButton) {

    let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    
    let popOverViewController = storyboard.instantiateViewController(withIdentifier: "PopoverViewController")
    
    popOverViewController.modalPresentationStyle = .popover
    
    let popover = popOverViewController.popoverPresentationController!
    
    popover.delegate = self
    
    popover.permittedArrowDirections = .up
    
    // The sourceView in the below code line represents the view containing the anchor rectangle for the popover:
    
    popover.sourceView = navigationBar.navigationBarRightButtonView
    
    // The sourceRect in the below code line represents The rectangle in the specified view in which to anchor the popover:
    
    popover.sourceRect = navigationBar.navigationBarRightButtonView.bounds
    
    present(popOverViewController, animated: true, completion:nil)
    

    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-08
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      • 1970-01-01
      • 2014-11-04
      • 1970-01-01
      相关资源
      最近更新 更多