Search code examples
iosswiftuibuttonuistoryboardsegue

How to pass UIButton's tag (an Int) to other ViewController using prepareForSegue (Swift 4, Xcode 9)


I am building an iOS app with 2 ViewControllers, the first being StartViewController.swift, the second being ViewController.swift.

StartViewController shows a number of 9 UIButtons, to each of which I have assigned an individual tag in Xcode's attributes inspector, namely integers from 0 to 8.

Every button represents some topic that the user would want to learn more about. Accordingly there is another file in my project where I created an array of headings and corresponding texts that represent the relevant information I want to show the user. The second VC (ViewController.swift) has 2 UILabels that show heading and text respectively.

In short, I want to grab the button’s tag (an Int) and use ist to output the topic information with the according index in my array.

I have connected both VCs with a UIStoryboardSegue that I named startToTopicSegue. Then I implemented the prepare(for segue: ) method and set up the buttons. With print statements I have confirmed that 1) the sender.tag in StartViewController.swift is indeed the tag of the tapped button, and 2) that the tagPassedOver variable sets the heading and text labels in the ViewController.swift as it should.

But tagPassedOver is not affected by what I specified in viewDidLoad() at all, instead it keep the init value of 0 - how do I change that?

I have the strong feeling that it has something to do with the specification of the sender in the first VC, but right now I am kind of lost in translation here, so any help would be appreciated ;) - thank you!

StartViewController.swift

@IBAction func buttonPressed(_ sender: UIButton) {
    print(sender.tag)

    performSegue(withIdentifier: "startToTopicSegue", sender: UIButton.self)
}

func prepare(for segue: UIStoryboardSegue, sender: AnyObject) {
    if segue.identifier == "startToTopicSegue"{
        let destinationVC = segue.destination as! ViewController
        destinationVC.tagPassedOver = sender.tag
    }
}

ViewController.swift

var tagPassedOver : Int = 0

@IBOutlet weak var headingLabel: UILabel!
@IBOutlet weak var textLabel: UILabel!

override func viewDidLoad() {

    headingLabel.text = allTopics.list[tagPassedOver].topicHeading
    textLabel.text = allTopics.list[tagPassedOver].topicText

Solution

  • You should be passing the instance of the UIButton whose tag you need.

    @IBAction func buttonPressed(_ sender: UIButton) { 
        print(sender.tag)
        performSegue(withIdentifier: "startToTopicSegue", sender: sender) // You have required button in sender, so pass that as sender
    }
    

    And in prepare method cast the sender to UIButton and retrieve it.

    func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "startToTopicSegue"{
            let destinationVC = segue.destination as! ViewController
            if let button = sender as? UIButton {
                destinationVC.tagPassedOver = button.tag
            }
        }
    }