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

如何给UIBarButtonItem加自定义动作及实现VC3直接返回VC1?

1. 如何给UIBarButtonItem添加自定义动作?

这里有几种常用的实现方式,你可以根据自己的需求来选:

  • 直接通过初始化方法绑定动作
    如果只是用系统样式的文字或图标按钮,初始化时就能直接指定触发对象和动作:
    // 文字按钮示例
    let customTextButton = UIBarButtonItem(title: "自定义", style: .plain, target: self, action: #selector(customTextButtonTapped))
    
    // SF Symbol图标按钮示例
    let customIconButton = UIBarButtonItem(image: UIImage(systemName: "plus"), style: .plain, target: self, action: #selector(customIconButtonTapped))
    
    // 将按钮添加到导航栏右侧
    navigationItem.rightBarButtonItem = customTextButton
    
    接着实现对应的触发方法就行,注意要加@objc标记:
    @objc func customTextButtonTapped() {
        // 这里写你的自定义逻辑
        print("文字按钮被点击啦")
    }
    
    @objc func customIconButtonTapped() {
        print("图标按钮被点击啦")
    }
    
  • 自定义UIButton作为UIBarButtonItem的视图
    如果需要更复杂的样式(比如自定义背景色、圆角、文字渐变),可以先做一个UIButton,再把它包装成UIBarButtonItem:
    let customStyleButton = UIButton(type: .system)
    customStyleButton.setTitle("专属样式", for: .normal)
    customStyleButton.setTitleColor(.orange, for: .normal)
    customStyleButton.layer.cornerRadius = 6
    customStyleButton.frame = CGRect(x: 0, y: 0, width: 80, height: 30)
    customStyleButton.addTarget(self, action: #selector(customStyleButtonTapped), for: .touchUpInside)
    
    let barButtonItem = UIBarButtonItem(customView: customStyleButton)
    navigationItem.leftBarButtonItem = barButtonItem
    
    对应的触发方法:
    @objc func customStyleButtonTapped() {
        // 执行你的自定义逻辑
    }
    
  • 小提醒
    动作方法必须带@objc,因为UIBarButtonItem的动作依赖Objective-C runtime识别;另外要确保target设置的是正确的对象(比如当前视图控制器的self)。
2. 实现VC3返回直接回到VC1

针对你说的VC1→VC2→VC3的导航流程,要让VC3点返回直接跳回VC1,有几种靠谱的方法:

方法一:自定义返回按钮,用popToViewController跳转

这种方式最直观,也最可控:

步骤1:替换VC3的系统返回按钮

在VC3的viewDidLoad里自定义返回按钮样式:

override func viewDidLoad() {
    super.viewDidLoad()
    // 创建自定义返回按钮,也可以用系统的返回图标
    let backToVC1Button = UIBarButtonItem(title: "返回首页", style: .plain, target: self, action: #selector(backToVC1Action))
    navigationItem.leftBarButtonItem = backToVC1Button
}

步骤2:实现返回逻辑

遍历导航栈找到VC1的实例,直接跳转回去:

@objc func backToVC1Action() {
    // 从导航栈中筛选出HomeViewController类型的实例
    if let vc1 = navigationController?.viewControllers.first(where: { $0 is HomeViewController }) {
        navigationController?.popToViewController(vc1, animated: true)
    } else {
        // 找不到VC1的话,默认退回到上一页作为兜底
        navigationController?.popViewController(animated: true)
    }
}

方法二:如果VC1是根控制器,用popToRootViewController

要是VC1刚好是UINavigationController的根控制器,那代码可以更简单:

@objc func backToVC1Action() {
    navigationController?.popToRootViewController(animated: true)
}

方法三:跳转时移除VC2(隐藏返回VC2的路径)

如果你希望从VC2跳转到VC3时,直接把VC2从导航栈里删掉,这样系统默认的返回按钮就会直接回到VC1。在VC2的didSelectItemAt代理方法里这么写:

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    let vc3 = NewViewController2()
    // 获取当前导航栈,保留到VC1的部分,再加上VC3
    if let currentStack = navigationController?.viewControllers, let vc2Index = currentStack.firstIndex(of: self) {
        var newStack = currentStack[0...vc2Index]
        newStack.removeLast() // 移除VC2
        newStack.append(vc3)
        navigationController?.setViewControllers(Array(newStack), animated: true)
    }
}

这种方式的好处是不用修改VC3的返回按钮,缺点是跳转动画还是push,但导航栈里已经没有VC2了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:16:11