You need to enable JavaScript to run this app. 如何获取navigationItem中rightBarButtonItems的视图位置坐标
优惠活动
大模型
产品
解决方案
定价
更多

如何获取navigationItem中rightBarButtonItems的视图位置坐标

无自定义视图UIBarButtonItem的坐标获取方案

基础说明

UIBarButtonItem本身并非UIView子类,没有直接暴露frame、center等坐标属性,它在导航栏上的实际渲染视图完全由UINavigationBar内部管理,不存在一步到位的公开属性可以直接拿到对应视图。

  • 弹系统popover场景(官方推荐,完全不用算坐标)
    做popover弹出根本不需要手动取CGPoint,苹果早就提供了原生适配接口:
    给UIPopoverPresentationController直接指定需要锚定的barButtonItem对象,系统会自动匹配浮层位置、箭头方向,横竖屏切换、分屏模式变化时也会自动跟随按钮调整位置,完全不需要手动处理坐标适配逻辑。
    参考实现代码:
    let popoverVC = UIViewController()
    popoverVC.modalPresentationStyle = .popover
    guard let popoverPC = popoverVC.popoverPresentationController else { return }
    // 直接绑定目标导航按钮作为锚点,无任何手动计算
    popoverPC.barButtonItem = infoBarButtonItem
    popoverPC.permittedArrowDirections = .up
    present(popoverVC, animated: true)
    
  • 需要手动获取坐标的自定义场景
    如果你要做自定义浮层、转场动画,确实需要拿到按钮在屏幕上的坐标,可以通过递归遍历导航栏视图层级,匹配对应按钮的承载交互视图,再通过UIKit原生坐标转换API拿到目标坐标系下的CGPoint值:
    实现步骤:
    1. 拿到当前导航控制器的UINavigationBar视图实例
    2. 递归遍历导航栏的所有子视图,匹配对应barButton的交互承载视图
    3. 调用convert(_:from:)方法将视图坐标转换到目标容器的坐标系下
      参考实现代码:
    func getBarItemCenter(for barItem: UIBarButtonItem, in coordinateView: UIView) -> CGPoint? {
      guard let navBar = navigationController?.navigationBar else { return nil }
      // 递归查找对应barButton的实际渲染视图
      func findRenderView(in subviews: [UIView]) -> UIView? {
        for view in subviews {
          // 匹配承载barButton交互的UIControl实例
          if let control = view as? UIControl, control.matches(barItem) {
            return control
          }
          if let matchedView = findRenderView(in: view.subviews) {
            return matchedView
          }
        }
        return nil
      }
      guard let renderView = findRenderView(in: navBar.subviews) else { return nil }
      // 把导航栏坐标系下的视图中心,转换到目标视图的坐标系
      return coordinateView.convert(renderView.center, from: navBar)
    }
    

注意事项

  • 不要通过KVC直接访问带私有前缀的内部属性(比如_view)来获取渲染视图,存在被App Store审核拒绝的风险
  • 必须等导航栏完成布局渲染后再获取视图坐标,否则会拿到frame为0的无效值
  • 坐标转换时要明确指定源坐标系和目标坐标系,避免出现浮层位置偏移

内容的提问来源于stack exchange,提问作者achu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.23 18:27:04