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

以编程方式创建Segue后,如何向第二个ViewController传递不同信息?

嘿,这个场景我太熟悉了——纯代码创建按钮和Segue的时候,没法像Storyboard里那样给Segue加标识符,确实会卡住一会儿。不过有几个实用的办法能解决,我给你捋一捋:

方法1:利用按钮Tag区分(最快捷)

这种方法不用额外写子类,靠按钮的tag属性来区分点击源,然后在Segue的准备方法里传递对应数据。

步骤:

  1. 创建按钮时给它们分配唯一的Tag,并绑定点击事件:
// 第一个按钮
let btn1 = UIButton(type: .system)
btn1.setTitle("传递信息A", for: .normal)
btn1.tag = 1
btn1.addTarget(self, action: #selector(onButtonTapped(_:)), for: .touchUpInside)
btn1.frame = CGRect(x: 50, y: 200, width: 200, height: 44)
view.addSubview(btn1)

// 第二个按钮
let btn2 = UIButton(type: .system)
btn2.setTitle("传递信息B", for: .normal)
btn2.tag = 2
btn2.addTarget(self, action: #selector(onButtonTapped(_:)), for: .touchUpInside)
btn2.frame = CGRect(x: 50, y: 260, width: 200, height: 44)
view.addSubview(btn2)
  1. 点击事件里触发Segue,并把按钮作为sender传递:
@objc func onButtonTapped(_ sender: UIButton) {
    // 编程创建Segue(如果没有从Storyboard拖的话)
    let destinationVC = SecondViewController()
    let segue = UIStoryboardSegue(source: self, destination: destinationVC)
    // 先执行准备逻辑,再触发Segue
    self.prepare(for: segue, sender: sender)
    segue.perform()
}
  1. 在prepare(for:sender:)里根据Tag判断,传递数据:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard let targetVC = segue.destination as? SecondViewController,
          let tappedBtn = sender as? UIButton else { return }
    
    switch tappedBtn.tag {
    case 1:
        targetVC.receivedData = "这是按钮1带来的消息"
    case 2:
        targetVC.receivedData = "这是按钮2带来的消息"
    default:
        targetVC.receivedData = "默认消息"
    }
}

(记得给SecondViewController加一个receivedData属性用来接收数据哦)

方法2:自定义Button子类(更优雅)

如果不想用Tag(毕竟Tag容易冲突、可读性差),可以给按钮加自定义属性,直接把要传递的数据存在按钮里。

步骤:

  1. 创建自定义Button子类:
class DataCarryingButton: UIButton {
    // 可以改成你需要的任意数据类型,比如模型对象
    var messageToPass: String?
}
  1. 创建按钮时直接赋值自定义数据:
let btnA = DataCarryingButton(type: .system)
btnA.setTitle("发送专属消息A", for: .normal)
btnA.messageToPass = "按钮A的私有消息"
btnA.addTarget(self, action: #selector(onCustomBtnTapped(_:)), for: .touchUpInside)
view.addSubview(btnA)

let btnB = DataCarryingButton(type: .system)
btnB.setTitle("发送专属消息B", for: .normal)
btnB.messageToPass = "按钮B的私有消息"
btnB.addTarget(self, action: #selector(onCustomBtnTapped(_:)), for: .touchUpInside)
view.addSubview(btnB)
  1. 点击处理和数据传递:
@objc func onCustomBtnTapped(_ sender: DataCarryingButton) {
    let targetVC = SecondViewController()
    let segue = UIStoryboardSegue(source: self, destination: targetVC)
    prepare(for: segue, sender: sender)
    segue.perform()
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard let targetVC = segue.destination as? SecondViewController,
          let tappedBtn = sender as? DataCarryingButton else { return }
    
    targetVC.receivedData = tappedBtn.messageToPass ?? "默认消息"
}
方法3:直接实例化目标VC(最灵活)

其实纯代码开发的时候,我个人更推荐这种方法——完全跳过Segue,直接创建目标ViewController,设置数据后导航过去,少了很多Segue的约束:

// 先把按钮存为实例变量,方便判断点击源
var btn1: UIButton!
var btn2: UIButton!

override func viewDidLoad() {
    super.viewDidLoad()
    
    btn1 = UIButton(type: .system)
    btn1.setTitle("直接跳转传信息1", for: .normal)
    btn1.addTarget(self, action: #selector(onDirectJumpTapped(_:)), for: .touchUpInside)
    view.addSubview(btn1)
    
    btn2 = UIButton(type: .system)
    btn2.setTitle("直接跳转传信息2", for: .normal)
    btn2.addTarget(self, action: #selector(onDirectJumpTapped(_:)), for: .touchUpInside)
    view.addSubview(btn2)
}

@objc func onDirectJumpTapped(_ sender: UIButton) {
    let targetVC = SecondViewController()
    
    // 根据点击的按钮设置数据
    if sender === btn1 {
        targetVC.receivedData = "直接跳转:按钮1的消息"
    } else if sender === btn2 {
        targetVC.receivedData = "直接跳转:按钮2的消息"
    }
    
    // 如果是导航控制器环境,push过去
    navigationController?.pushViewController(targetVC, animated: true)
    // 如果是模态展示,用这个:
    // present(targetVC, animated: true)
}

这种方式代码更直观,不用管Segue的标识符或者准备方法,完全由你控制流程,特别适合纯代码搭建的界面。


内容的提问来源于stack exchange,提问作者Aurel Calin Muth

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:36:03