单击触发打开另一个 VC 的按钮时如何将按钮 sender.tag 传递给另一个 VC
How to pass button's sender.tag to another VC when clicking a button which triggering open another VC
我正在使用自定义 tableView Cell,它在 VC1 中有一个按钮和一些标签。我想做的是当我连续点击按钮时,然后打开VC2并将当前标签的文本(名称[i])发送到VC2。
但在我的例子中,我坚持如何在 pressButton 函数中传递 buttonTag 来准备函数 controller.playingSong = names[buttonTag]
。我尝试使用全局变量,然后每次 prepare() 检索该变量,但它不起作用 属性,似乎 prepare() 将在 pressButton() 方法之前执行。
好吧,我搜索了很多但没有得到解决方案,我可以将prepare()结合到我的pressButton()中,换句话说,使用segue时是否需要prepare?
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var myTableView: UITableView!
let REUSE_ID = "CustomCell"
var names = ["first", "second", "third"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func pressButton(_ sender: UIButton) {
let buttonTag = sender.tag
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: REUSE_ID, for: indexPath) as! CustomCell
cell.myButton.tag = indexPath.row
cell.songName.text = names[indexPath.row]
// cell.myButton.addTarget(self, action: #selector(self.pressButton(_:)), for: .touchUpInside)
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "playingSongs":
let controller = segue.destination as! OpenedVC
controller.playingSong = names[buttonTag]
default: break
}
}
}
听起来您正在为您的按钮附加一个 segue。您可以这样做,或者使用按钮 IBAction。如果您同时执行这两项操作,我认为它无法正常工作,这可能是您遇到的问题。
如果你的按钮按下触发了一个 IBAction,你可以从 sender 参数中获取按钮标签到动作,然后让你的 IBAction 代码实例化视图控制器并设置视图的 属性控制器在显示之前发送给发送者标签。
如果您想将一个 segue 附加到按钮,那么 prepare(for:sender:)
方法将在 sender 参数中传递给按钮。然后,您可以尝试将 sender 转换为 UIButton,如果转换成功,则获取按钮的标签并将其传递给目标视图控制器。像这样:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "playingSongs":
if let sendingButton = sender as? UIButton,
let controller = segue.destination as? OpenedVC { //Don't use a force-cast
let buttonTag = sendingButton.tag
controller.playingSong = names[buttonTag]
}
// The rest of your code to follow
}
}
编辑:
我通过将 if let
可选绑定中的两个转换更改为使用 as?
.
来修复上面的代码
请注意,您应该避免强制转换 (as!
),因为如果失败会导致崩溃。
您不必重写准备功能。
只需在 pressButton 函数中编写准备函数的代码,但稍作修改,如下所示:
@IBAction func pressButton(_ sender: UIButton) {
let controller = self.storyboard?.instantiateViewController(withIdentifier: "YourView's StoryBoardID") as! OpenedVC
controller.playingSong = names[sender.tag]
present(viewControllerToPresent: controller, animated: true, completion: nil)
}
希望我的回答对您有所帮助:)
如果"segue is from Button"
,您需要更改此处
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "playingSongs":
let controller = segue.destination as! ViewController
controller.playingSong = names[(sender as! UIButton).tag] //Need Change here
default: break
}
}
我正在使用自定义 tableView Cell,它在 VC1 中有一个按钮和一些标签。我想做的是当我连续点击按钮时,然后打开VC2并将当前标签的文本(名称[i])发送到VC2。
但在我的例子中,我坚持如何在 pressButton 函数中传递 buttonTag 来准备函数 controller.playingSong = names[buttonTag]
。我尝试使用全局变量,然后每次 prepare() 检索该变量,但它不起作用 属性,似乎 prepare() 将在 pressButton() 方法之前执行。
好吧,我搜索了很多但没有得到解决方案,我可以将prepare()结合到我的pressButton()中,换句话说,使用segue时是否需要prepare?
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var myTableView: UITableView!
let REUSE_ID = "CustomCell"
var names = ["first", "second", "third"]
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func pressButton(_ sender: UIButton) {
let buttonTag = sender.tag
}
}
extension ViewController: UITableViewDataSource, UITableViewDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return names.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: REUSE_ID, for: indexPath) as! CustomCell
cell.myButton.tag = indexPath.row
cell.songName.text = names[indexPath.row]
// cell.myButton.addTarget(self, action: #selector(self.pressButton(_:)), for: .touchUpInside)
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "playingSongs":
let controller = segue.destination as! OpenedVC
controller.playingSong = names[buttonTag]
default: break
}
}
}
听起来您正在为您的按钮附加一个 segue。您可以这样做,或者使用按钮 IBAction。如果您同时执行这两项操作,我认为它无法正常工作,这可能是您遇到的问题。
如果你的按钮按下触发了一个 IBAction,你可以从 sender 参数中获取按钮标签到动作,然后让你的 IBAction 代码实例化视图控制器并设置视图的 属性控制器在显示之前发送给发送者标签。
如果您想将一个 segue 附加到按钮,那么 prepare(for:sender:)
方法将在 sender 参数中传递给按钮。然后,您可以尝试将 sender 转换为 UIButton,如果转换成功,则获取按钮的标签并将其传递给目标视图控制器。像这样:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "playingSongs":
if let sendingButton = sender as? UIButton,
let controller = segue.destination as? OpenedVC { //Don't use a force-cast
let buttonTag = sendingButton.tag
controller.playingSong = names[buttonTag]
}
// The rest of your code to follow
}
}
编辑:
我通过将 if let
可选绑定中的两个转换更改为使用 as?
.
请注意,您应该避免强制转换 (as!
),因为如果失败会导致崩溃。
您不必重写准备功能。
只需在 pressButton 函数中编写准备函数的代码,但稍作修改,如下所示:
@IBAction func pressButton(_ sender: UIButton) {
let controller = self.storyboard?.instantiateViewController(withIdentifier: "YourView's StoryBoardID") as! OpenedVC
controller.playingSong = names[sender.tag]
present(viewControllerToPresent: controller, animated: true, completion: nil)
}
希望我的回答对您有所帮助:)
如果"segue is from Button"
,您需要更改此处override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
switch segue.identifier {
case "playingSongs":
let controller = segue.destination as! ViewController
controller.playingSong = names[(sender as! UIButton).tag] //Need Change here
default: break
}
}