Swift: Make button trigger segue to new scene

前端 未结 3 1755
挽巷
挽巷 2020-12-14 02:12

Alright, so I have a TableView scene and I\'m going to put a button in each of the cells and I need each cell to, when clicked, segue to its own

相关标签:
3条回答
  • 2020-12-14 02:17

    You can use the delegation pattern. Presuming that you have implemented a custom table cell, you can define a property in its class to hold whatever you think is helpful to identify the row - it can be its index, or (my preferred way) an instance of a class which represents the data displayed in the cell (I'm calling it MyCellData.

    The idea is to let the cell notify the table view controller about a tap on that button, passing relevant data about (the data displayed in) the row. The table view controller then launches a segue, and in the overridden prepareForSegue method it stores the data passed by the cell to the destination controller. This way if you have to display details data about the row, you have all the relevant info, such as the details data itself, or an identifier the destination view controller can use to retrieve the data for example from a local database or a remote service.

    Define a protocol:

    protocol MyCellDelegate {
        func didTapMilk(data: MyCellData)
    }
    

    then declare a property named delegate in the cell class, and call its didTapMilk method from the IBAction

    class MyTableCell : UITableViewCell {
        var delegate: MyCellDelegate?
        var data: MyCellData!
    
        @IBAction func didTapMilk() {
            if let delegate = self.delegate {
                delegate.didTapMilk(self.data)
            }
        }
    }
    

    Next, implement the protocol in your table view controller, along with an override of prepareForSegue

    extension MyTableViewController : MyCellDelegate {
        func didTapMilk(data: MyCellData) {
            performSegueWithIdentifier("mySegueId", sender: data)
        }
    
        override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
            if segue.identifier == "mySegueId" {
                let vc: MyDestinationViewController = segue.destinationViewController as MyDestinationViewController
                vc.data = sender as? MyCellData
            }
        }
    }
    

    Of course you need a data property on your destination view controller for that to work. As mentioned above, if what it does is displaying details about the row, you can embed all required data into your MyCellData class - or at least what you need to retrieve the data from any source (such as a local DB, a remote service, etc.).

    Last, in cellForRowAtIndexPath, store the data in the cell and set its delegate property to self:

    extension MyTableViewController : UITableViewDataSource {
        override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
            let data: MyCellData = retrieveDataForCell(indexPath.row) // Retrieve the data to pass to the cell
            let cell = self.tableView.dequeueReusableCellWithIdentifier("myCellIdentifier") as MyTableCell
            cell.data = data
            cell.delegate = self
    
            // ... other initializations
    
            return cell
        }
    }
    
    0 讨论(0)
  • 2020-12-14 02:33

    Use self.performSegueWithIdentifier("yourViewSegue", sender: sender) under your event for handling button's click:

    @IBAction func redButtonClicked(sender: AnyObject) {
        self.performSegueWithIdentifier("redView", sender: sender)
    }
    

    In the above code, redView is the segue identifier.

    0 讨论(0)
  • 2020-12-14 02:43

    If you want to have a button trigger the segue transition, the easiest thing to do is Control+Click from the button to the view controller and choose a Segue option (like push). This will wire it up in IB for you.

    If you want to write the code to do this yourself manually, you can do so by naming the segue (there's an identifier option which you can set once you've created it - you still need to create the segue in IB before you can do it) and then you can trigger it with this code:

    V2

    @IBAction func about(sender: AnyObject) {
        performSegueWithIdentifier("about", sender: sender)
    }
    

    V3

    @IBAction func about(_ sender: Any) {
        performSegue(withIdentifier: "about", sender: sender)
    }
    
    0 讨论(0)
提交回复
热议问题