You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取导航栏(NavBar)中标题的X和Y坐标?

解决导航栏标题坐标获取的问题

这个问题我之前也踩过坑,核心问题在于你混淆了bounds和frame的区别,而且如果时机不对,titleView可能还没完成布局,自然拿不到正确的值~

下面分两种常见场景给你解决方案:


场景1:你自定义了titleView(通过Storyboard或代码设置的自定义视图)

首先要等视图布局完成后再获取坐标,推荐在viewDidLayoutSubviews方法里操作——这个方法会在视图所有子控件布局完成后调用,此时titleView的frame才是准确的:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    // 获取标题视图相对于导航栏的坐标
    if let titleView = navigationItem.titleView {
        let navBarRelativeOrigin = titleView.frame.origin
        print("标题相对于导航栏的X:\(navBarRelativeOrigin.x),Y:\(navBarRelativeOrigin.y)")
        
        // 如果需要相对于屏幕的坐标,用坐标系转换方法
        let screenRelativeOrigin = titleView.convert(titleView.bounds.origin, to: nil)
        print("标题相对于屏幕的X:\(screenRelativeOrigin.x),Y:\(screenRelativeOrigin.y)")
    }
}

场景2:使用系统默认的导航栏标题(未自定义titleView)

这种情况下navigationItem.titleView是nil,你需要遍历导航栏的子视图找到内置的标题Label:

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    // 遍历导航栏子视图,筛选出标题Label
    if let titleLabel = navigationController?.navigationBar.subviews.first(where: { $0 is UILabel }) as? UILabel {
        let navBarRelativeOrigin = titleLabel.frame.origin
        print("默认标题相对于导航栏的X:\(navBarRelativeOrigin.x),Y:\(navBarRelativeOrigin.y)")
        
        // 转换为屏幕坐标系的坐标
        let screenRelativeOrigin = titleLabel.convert(titleLabel.bounds.origin, to: nil)
        print("默认标题相对于屏幕的X:\(screenRelativeOrigin.x),Y:\(screenRelativeOrigin.y)")
    }
}

关键提示

  • 绝对不要在viewDidLoad里直接获取坐标!此时视图还没完成布局,titleView的frame还未确定,大概率返回nil或错误值;
  • bounds是视图自身的坐标系,原点默认是(0,0),所以用它拿坐标完全不对,要获取相对于父视图或屏幕的位置,必须用frame或者坐标系转换方法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:18:37