0

I am new to IOS and basically I have a tableView and whenever it has 40 cells and each cell has a stepper and a label. the label displays the stepper's value. The tableview generates the cells fine, but the problem is that whenever I click the stepper in one cell, some other random cells also have their steppers activated.This is swift by the way. Here is the code for the cell:

import UIKit

class StudentTableViewCell: UITableViewCell {
@IBOutlet weak var studentNameAndValue: UILabel!
@IBOutlet weak var studentValueChanger: UIStepper!

let name:String?
let value:Int?
override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code

}

override func setSelected(selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

    // Configure the view for the selected state
}
@IBAction func stepperValueChanged(sender: AnyObject) {
    studentNameAndValue.text = "\(name): \(Int(studentValueChanger.value))"
}

}

Here is the code for the viewcontroller:

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    tableView.delegate = self
    tableView.dataSource = self
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 40
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("studentCell") as StudentTableViewCell
    return cell
}
}
dhruvm
  • 2,672
  • 2
  • 19
  • 24

1 Answers1

1

The problem is in your table view controller. It would be better to put the value-changed method there. Alternatively, review your cellForRowAtIndexPath method. You are not updating the cells correctly when they are recycled.

You have to set the value of stepper and label explicitly in cellForRowAtIndexPath. You cannot read these values from the cell - they should be in your datasource (i.e. the table view controller should know what to display for a given index path).

Connect the stepper handler to the method in the view controller, then identify the proper index path via the sender argument.

@IBAction func stepperChanged(sender: UIStepper) {
    let point = sender.convertPoint(CGPointZero, toView: tableView)
    let indexPath = self.tableView.indexPathForRowAtPoint(point)!
    let myData = dataArray[indexPath.row] // or whatever your datasource
    // if you need to update the cell
    let cell = self.tableView.cellForRowAtIndexPath(indexPath)
}
Mundi
  • 79,884
  • 17
  • 117
  • 140
  • how would I put the value-changed method in the table view controller and connect it to the actual stepper and label? – dhruvm Feb 16 '15 at 19:57
  • Connect it in storyboard from the prototype cell. In the handler, you can identify the `sender`. I will add some code to my answer to demonstrate. – Mundi Feb 16 '15 at 20:02
  • but if we are connecting the stepper and the label inside the view controller, we would have to connect them inside the cellForRowAtIndexPath method. right? – dhruvm Feb 16 '15 at 20:11
  • No. The stepper is part of the dequeued cell already. You connect them in **storyboard**. – Mundi Feb 16 '15 at 20:13
  • okay. so I don't have to put the stepperChanged method inside cellForRowAtIndexPath because I can already retrieve the point using sender – dhruvm Feb 16 '15 at 20:36
  • It still doesn't work. When I added the stepperChanged method in the view controller instead, it worked but other labels from other cells still changed too. – dhruvm Feb 16 '15 at 20:47
  • this is what the method looked like for testing: – dhruvm Feb 16 '15 at 20:48
  • @IBAction func stepperChangerMethod(sender: UIStepper) { let point = sender.convertPoint(CGPointZero, toView: tableView) let indexPath = self.tableView.indexPathForRowAtPoint(point) let cell = self.tableView.cellForRowAtIndexPath(indexPath!) as StudentTableViewCell cell.studentNameAndValue.text = "" } – dhruvm Feb 16 '15 at 20:48
  • Did you change the `cellForRowAtIndexPath` method? – Mundi Feb 16 '15 at 20:48
  • I can't put the IBAction inside cellForRowAtIndexPath method, It gives me an error, I have to put the IBAction outside cellForRowAtIndexPath – dhruvm Feb 16 '15 at 20:55
  • what should my cellForRowAtIndexPath method look like? – dhruvm Feb 16 '15 at 20:57
  • OK, slow down. If you tried that, you have not understood how the architecture works. Please read this thread carefully a couple of times and perhaps consult the documentation about the mentioned methods. Then try to implement it carefully while observing what you learned. Then, after you are done with that - post again to this thread if you need help. – Mundi Feb 16 '15 at 20:57