簡體   English   中英

如何從自定義導航欄右鍵顯示PopoverViewController?

[英]How to display a PopoverViewController from a custom Navigation Bar Right Button?

我創建了一個自定義的Navigation Bar類,如下所示,該類在多個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),

            ])

    }

}

我使用下面的代碼設法解決了我的問題,一開始讓我感到困惑的是我使用的是獨立的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)

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM