【问题标题】:How to pass button's sender.tag to another VC when clicking a button which triggering open another VC单击触发打开另一个VC的按钮时如何将按钮sender.tag传递给另一个VC
【发布时间】:2020-01-20 11:57:57
【问题描述】:

我正在使用自定义 tableView 单元格,它在 VC1 中有一个按钮和一些标签。我想要做的是当我连续单击按钮时,然后打开 VC2 并将当前标签的文本(名称 [i])发送到 VC2。

但就我而言,我坚持如何在 pressButton func 中传递 buttonTag 以准备 func 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
        }
    }
}

【问题讨论】:

    标签: swift button tableview segue


    【解决方案1】:

    听起来您在按钮上附加了一个 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!),因为如果它失败会导致崩溃。

    【讨论】:

    • 感谢您的回复,尝试使用您的代码,但 Xcode 提示我 'Any?' is not convertible to 'UIButton'; did you mean to use 'as!' to force downcast? 都为 sendercontroller。如果我使用! 强制转换,那么它会提示我Initializer for conditional binding must have Optional type, not 'OpenedVC'
    • 作为一个 Swift 新手开发者,你应该假装as! 强制转换运算符不存在(强制解包! 运算符也是如此。)将! 视为“崩溃”如果为零”运算符。 (和as!“如果演员失败则崩溃”运算符。)我将编辑我的答案以使用as?,这就是你想要的。 (我忘记了那部分。)
    • 首先,它现在可以工作了,谢谢。你是第二个要求我不要使用! 的人,是的,这是正确的,我是 Swift 的初级人员,有时我只是懒得使用 Xcode 建议来更正我的代码或拒绝使用?? default,因为它打字多了……
    • 如果我的回答解决了你的问题,你应该接受它。 (这是本网站的预期行为。对好的答案进行投票是可选的,但受到鼓励。但是,您需要为此获得更多声誉。)
    • 了解编程中的懒惰很像电线的懒惰。它可能会在现在为您节省几分钟,并导致您的房子(应用程序)在未来的某个时候被烧毁。
    【解决方案2】:

    如果“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
        }
    }
    

    【讨论】:

    • 太棒了!它也有效,我愚蠢的大脑没有想出使用发件人来传递按钮。标签:(实际上你的方法和 Nouraiz Taimour 的方法可能是 Duncan C 的回答中提到的两种方法。
    【解决方案3】:

    您不一定要重写准备函数。

    只需在 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 以及 VC1 中的 prepare() 时,您的代码工作正常。我缺的可能就是这个self.storyboard?.instantiateViewController(withIdentifier: "YourView's StoryBoardID"),我根本不知道这个方法……
    • 这个方法只是用给定的标识符创建当前情节提要中存在的视图控制器的实例
    猜你喜欢
    • 2018-11-21
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 1970-01-01
    • 2020-03-15
    • 1970-01-01
    相关资源
    最近更新 更多