在 Swift 中获取导航栏项目按钮的位置

Posted

技术标签:

【中文标题】在 Swift 中获取导航栏项目按钮的位置【英文标题】:Get position of navigation bar item button in Swift 【发布时间】:2020-01-16 13:03:29 【问题描述】:

我想获取我的导航项的位置(点),这是一个按钮。如果我能得到这一点,我将能够在我的应用程序上添加一个引导圈。但我不能正确理解这一点。

let point = searchBarButton.center

let point = view.convert(CGPoint(x: searchBarButton.center.x, y: searchBarButton.center.y + UIApplication.shared.statusBarFrame.height), from: view)

y 点在我添加状态栏高度时计算正确。但是x 点的值始终为20,这没有意义。那么如何正确获取x 点呢?

这是我的代码和我的应用程序的屏幕截图。

class ViewController: UIViewController 

    let searchBarButton = UIButton()

    // MARK: - viewDidLoad
    override func viewDidLoad() 
        super.viewDidLoad()

        configureNavigationBarItems()

        let added_view: UIView = navigationController?.view ?? view
        let point = added_view.convert(CGPoint(x: searchBarButton.center.x, y: searchBarButton.center.y + UIApplication.shared.statusBarFrame.height), from: added_view)
        addCircle(point: point)

    

    func configureNavigationBarItems() 

        searchBarButton.setImage(UIImage(named: "icon_search_border"), for: .normal)
        searchBarButton.frame = CGRect.init(x: 0, y: 0, width: 40, height: 40)
        let searchBarButtonItem = UIBarButtonItem.init(customView: searchBarButton)

        self.navigationItem.setRightBarButton(searchBarButtonItem, animated: true)

    

    func addCircle(point: CGPoint) 

        let overlayView = UIView(frame: self.view.bounds)
        overlayView.backgroundColor = UIColor.black.withAlphaComponent(0.5)
        self.navigationController?.view.addSubview(overlayView)

        let circlePath = UIBezierPath(arcCenter: point,
                                      radius: 30,
                                      startAngle: 0.0,
                                      endAngle: 2.0 * .pi,
                                      clockwise: true)

        let path = CGMutablePath()
        path.addPath(circlePath.cgPath)
        path.addRect(overlayView.frame)

        let maskLayer = CAShapeLayer()
        maskLayer.path = path
        maskLayer.fillRule = .evenOdd

        overlayView.layer.mask = maskLayer
        overlayView.layer.masksToBounds = true

    


【问题讨论】:

【参考方案1】:

当您想要访问导航栏项目时,您应该在 viewDidAppear 中访问它们,这就是我的问题的答案。它的灵感来自@jawadAli 的回答。

override func viewDidAppear(_ animated: Bool) 
    super.viewDidAppear(animated)

    if let navigationBarSubviews = self.navigationController?.navigationBar.subviews 
        for view in navigationBarSubviews 

            if let findClass = NSClassFromString("_UINavigationBarContentView"),
                view.isKind(of: findClass),
                let barButtonView = self.navigationItem.rightBarButtonItem?.value(forKey: "view") as? UIView 

                let point = barButtonView.convert(barButtonView.center, to: view)
                addCircle(point: CGPoint(x: point.x, y: point.y + UIApplication.shared.statusBarFrame.height))
            
        
    


【讨论】:

以上是关于在 Swift 中获取导航栏项目按钮的位置的主要内容,如果未能解决你的问题,请参考以下文章

Swift UI 2 DocumentGroup 获取导航栏按钮操作

导航栏按钮项目的图像 swift

Swift:如何通过按导航栏按钮访问标签栏项目

不在导航栏上制作栏按钮项目和标题(iOS,Swift)

在导航栏中自动添加“返回”按钮

Swift - 修改导航栏“返回”按钮文字,图标