Matty
Matty

Reputation: 343

SWIFT - UITableViewCell updating based on selection

I have a TableViewController (lets call TVC1) with a row that says "OD" (which stands for Outer Diameter).

Upon selecting this row, a bunch of rows in a new TableViewController (lets call TVC2) containing the various OD (casingOD in my code) shows. What I want to happen is when the user selects the OD it will segue back to the main TableViewController with the string that corresponds to the user selection. My code for this currently fails...Could anyone help point me in the right direction? If you require TVC1 code i'll happily post it, i'm just trying to save any unneccessary code reading for you folks :)

My TVC2 code is as follows:

import UIKit

class CasingSelectionTableViewController: UITableViewController {

var selectedData: Data?

let casingOD = ["114.3", "127.0", "139.7", "168.3" , "177.8", "193.7", "219.1", "244.5", "247.6", "273.1", "298.4", "298.4", "339.7", "406.4", "473.0", "508"]

override func viewDidLoad() {
    super.viewDidLoad()
}

override func viewWillAppear(animated: Bool) {
    switch selectedData! {

    case .OuterDiameter:
        print(casingOD)

    case .Weight:
        print(casingWeight114) // I deleted the casingWeight114 line of code as its not required for this question

    case .InnerDiameter:
        print(id114) // I deleted the id114 line as its not required for this question
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return casingOD.count

}


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var casingSpec: UITableViewCell!

    if selectedData == Data.OuterDiameter {
        casingSpec = tableView.dequeueReusableCellWithIdentifier("selectedCasingSpec", forIndexPath: indexPath)
        let casingODSpec = casingOD[indexPath.row]
        casingSpec.textLabel?.text = casingODSpec
        return casingSpec
    } else {
        return casingSpec
    }

}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let selection: UITableViewCell!
    selection.textLabel?.text = indexPath.row as! String

}

Upvotes: 0

Views: 1024

Answers (2)

mokagio
mokagio

Reputation: 17471

What I want to happen is when the user selects the OD it will segue back to the main TableViewController with the string that corresponds to the user selection.

First of all you'll need to implement a way for TVC2 to notify TVC1 that a value has been selected.

A common way to do such thing is by using delegation. You can define a delegate protocol like this:

protocol TVC2Delegate {
    func tvc2(tvc2: TVC2, didSelectOuterDiameter outerDiameter: String)
}

Then add a var delegate: TVC2Delegate? property to TVC2.

You'll then make TVC1 comform to TVC2Delegate by implementing that method in TVC1.

When presenting TVC2 from TVC1 remember to set it as the delegate for TVC2.

// In TVC1
tvc2.delegate = self

To connect TVC1 and TVC2 you could add a bit o logic to your tableView(tableView:,didSelectRowAtIndexPath:) method call the delegate with the selected value

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let stringValue = indexPath.row as! String

    // Do anything you need to do related to TVC2 here.
    // Then finally

    delegate?.tvc2(self, didSelectOuterDiameter: stringValue)
}

Finally, in TVC1's implementation of the delegate method you can take care of dismissing TVC2 if needed.

Update:

This is how the final implementation of these bits might look like:

// In TVC1
class TVC1: UITableViewController, TVC2Delegate {

    // ...

    // Implement the method(s) of TVC2Delegate
    func tvc2(tvc2: TVC2, didSelectOuterDiameter outerDiameter: String) {
        // Do whatever you need to do with the outerDiameter parameter
    }

}

// In TVC2
protocol TVC2Delegate {
    func tvc2(tvc2: TVC2, didSelectOuterDiameter outerDiameter: String)
}

class CasingSelectionTableViewController: UITableViewController {

    var delegate: TVC2Delegate?

    // ...

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let stringValue = casingOD[indexPath.row]

        // Do anything you need to do related to TVC2 here.
        // Then finally

        delegate?.tvc2(self, didSelectOuterDiameter: stringValue)
    }
}

Upvotes: 1

Fayza Nawaz
Fayza Nawaz

Reputation: 2316

Use the delegate approach as suggested in the answer by @Mokagio. And in case you're having issue in getting the string, here is the answer

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

let cell = tableView.cellForRowAtIndexPath(indexPath) as! UITableViewCell
let stringValue = cell.textLabel.text  //You can get this from your datasource as well)

//call the delegate

}

Upvotes: 1

Related Questions