I have a problem with the following scenario:
I have an UITableView
with dynamic cells. Among others, I use a custom UITableViewCell
with a UISlider
. How can I get the values of the sliders?
I created the following example: (The project file can be downloaded here: Link)
SliderClass.swift
import UIKit
class SliderClass: NSObject {
var title: String
var subtitle: String
var sliderMinimum: Float
var sliderMaximum: Float
init(title: String, subtitle: String, sliderMinimum: Float, sliderMaximum: Float) {
self.title = title
self.subtitle = subtitle
self.sliderMinimum = sliderMinimum
self.sliderMaximum = sliderMaximum
}
}
SliderTableViewCell.swift
import UIKit
class SliderTableViewCell: UITableViewCell {
@IBOutlet weak var cellTextLabel: UILabel!
@IBOutlet weak var cellDetailTextLabel: UILabel!
@IBOutlet weak var cellSlider: UISlider!
override func awakeFromNib() {
super.awakeFromNib()
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
}
}
TableViewController.swift
import UIKit
class TableViewController: UITableViewController {
var slider: [SliderClass] = []
override func viewDidLoad() {
super.viewDidLoad()
title = "Slider"
let slider1 = SliderClass(title: "Title1", subtitle: "Subtitle1", sliderMinimum: 0, sliderMaximum: 100)
let slider2 = SliderClass(title: "Title2", subtitle: "Subtitle2", sliderMinimum: 0, sliderMaximum: 200)
slider = [slider1, slider2]
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return slider.count
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("sliderCell", forIndexPath: indexPath) as! SliderTableViewCell
let slider: SliderClass
slider = self.slider[indexPath.row]
cell.cellTextLabel.text = slider.title
cell.cellDetailTextLabel?.text = slider.subtitle
cell.cellSlider.minimumValue = slider.sliderMinimum
cell.cellSlider.maximumValue = slider.sliderMaximum
return cell
}
func sliderValueChange() {
// I need help here:
// Which slider changed to which value?
// var slider = ...
// var sliderValue = ...
// NSLog("Value of slider:%@ changed to:%i", slider, sliderValue)
}
}
Here is a screenshot of the UITableView created with the code above.
Try adding this to your cellForRowAtIndexPath
function:
cell.cellSlider.tag = indexPath.row
cell.cellSlider.addTarget(self, action: "sliderValueChange:", forControlEvents: .ValueChanged)
And then outside of the table function add something like:
func sliderValueChange(sender: UISlider) {
// Get the sliders value
var currentValue = Int(sender.value)
var sliderRow = sender.tag
// Do whatever you want with the value :)
// And now the row of the slider!
}
Make sure the action name for cellSlider
's target is the same as the function's name! And since it takes one argument, don't forget the colon at the end.
So just to summarise, here's a really simply example of the above in action:
import UIKit
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2 // 2 rows in the cell, for demo purposes
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! TableViewCell
cell.slider.tag = indexPath.row
cell.slider.addTarget(self, action: "sliderChange:", forControlEvents: .ValueChanged)
return UITableViewCell()
}
func sliderChange(sender: UISlider) {
let currentValue = sender.value // get slider's value
let row = sender.tag // get slider's row in table
print("Slider in row \(row) has a value of \(currentValue)")
// example output - Slider in row 1 has a value of 0.601399
}
}
class TableViewCell: UITableViewCell {
@IBOutlet var slider: UISlider!
}