I'm activating a function in my custom cell class from a viewController. The custom cell class looks like this:
import UIKit
class TableViewCell: UITableViewCell {
var counter = 10
class func timerStarted(){
var timer = NSTimer()
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update", userInfo: nil, repeats: true)
}
class func update(){
let cell = TableViewCell()
var count = cell.counter
count = --count
println(counter)
}
}
The problem is that the variable counter does not change, so 9 is printed every interval. How do I make it so that it changes value every time and counts down?
Any suggestions would be appreciated.
EDIT: I'm using a long press gesture recognizer to trigger the function, which is the reason I can't just trigger it using a didSelectRowAtIndexPath-function. My code for the long press looks like this:
func longPressActive(gestureRecognizer:UIGestureRecognizer) {
if (gestureRecognizer.state == UIGestureRecognizerState.Began) {
var point = gestureRecognizer.locationInView(self.tv)
if let indexPath = self.tv.indexPathForRowAtPoint(point) {
TableViewCell.timerStarted()
}
}
}
Alright, so your problem is that you are calling a class method on the TableView class rather than an instance function. You want to get a handle on an actual cell instance, not just the class. So first, your TableCell class with the proper signatures (i.e. remove the class
prefix):
class TableViewCell: UITableViewCell {
var counter = 10
// No longer class functions! :)
func timerStarted(){
var timer = NSTimer()
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update", userInfo: nil, repeats: true)
}
func update() {
// Update counter
counter-- // <-- performs the actual decrement for you
println(counter)
}
}
Then just update your long press to activate the timer on an actual cell, not just the cell's class:
func longPressActive(gestureRecognizer:UIGestureRecognizer) {
if (gestureRecognizer.state == UIGestureRecognizerState.Began) {
var point = gestureRecognizer.locationInView(self.tv)
if let indexPath = self.tv.indexPathForRowAtPoint(point) {
// Check to make sure it is the correct subclass
if let cell = self.tv.cellForRowAtIndexPath(indexPath: indexPath) as? TableViewCell {
// Starting the timer on the actual cell, not just the cell class
cell.timerStarted();
}
}
}
}
Also, I want to make a comment about your timerStarted()
function. You first create a new timer and assign it to timer
and then you create a second timer and assign that to timer
as well, redundant. Also, since you are not saving the timer outside that method there is no need to create a variable (to keep your same functionality). So the function could be:
func timerStarted(){
NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update", userInfo: nil, repeats: true)
}
But there is a good chance you will want to cancel this at some point, so I would probably store it as an instance variable:
private var timer: NSTimer
func timerStarted(){
self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update", userInfo: nil, repeats: true)
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let cell = tableView.cellForRowAtIndexPath(indexPath) as TableViewCell
cell.timerStarted()
}
For your tableview cell class:
func timerStarted(){
var timer = NSTimer()
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update", userInfo: nil, repeats: true)
}
func update(){
counter = counter - 1
println(counter)
}