when i try to use integer variable as a timer interval in NSTimer in swift i get " extra argument "selector in call"
this is the code :
var count = 3
var Timer = NSTimer()
#IBAction func playButtonPressed(sender: AnyObject) {
Timer = NSTimer.scheduledTimerWithTimeInterval(count, target: self, selector: Selector("result"),userInfo: nil, repeats: true)
}
if i put 3 instead of count it works perfectly
i want to be able to give the user the advantage to set the interval himself.
The NSTimer.scheduledTimerWithTimeInterval takes a Double for that first parameter. Try using:
var count: Double = 3.0
Related
My code is here:
#IBAction func updateTime(){
let inputVal: String = textMinutes.text!
var inputInt = Int(inputVal)
timerLabel?.text = "\(inputInt)"
if inputInt != 0 {
inputInt -= 1
}
else {
endTimer()
}
So on the inputInt -=1 I keep getting the error "Cannot convert value of type 'Int?' to expected argument type 'inout Int'". I am not sure how to fix this or if my code is even correct here. This is all for this:
func startTimer() {
countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(ViewController.updateTime), userInfo: nil, repeats: true)
}
which is for the timer I am trying to make. I am pretty new to this so if there is anything else you need to see I can post it. I've looked all over for solutions but I have not found anything. Thanks in advance.
Your logic is bad. You don't want to change text of some label every second according to same other text every time.
You should create global variable for time, let's say interval
class ViewController: UIViewController {
var interval = 0
...
}
then when you start timer, make sure that user wrote number and if does, start timer and set interval
func startTimer() {
if let interval = Int(textMinutes.text!) {
self.interval = interval
timerLabel?.text = String(interval)
countdownTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(ViewController.updateTime), userInfo: nil, repeats: true)
} else {
... // handle case if user didn’t write integer
}
}
then every time timer updates, just decrease interval and change text of your text field by this interval variable, then when interval is 0, invalidate your timer
#IBAction func updateTime() {
interval -= 1
timerLabel?.text = String(interval)
if interval == 0 { endTimer() }
}
I want to start a timer at a specific date and time, then use that start time as a game timer for the rest of the game. Using "timeIntervalSinceDate" will give me seconds but then trying to get the seconds to display on the gameTimerLabel won't work. I might be coming at this the wrong way. Any advice is welcome.
override func viewWillAppear(animated: Bool) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss zzz"
let dateAsString1 = "Fri, 1 April 2016 11:30:00 MST"
let date1 = dateFormatter.dateFromString(dateAsString1)!
var currentTime = NSDate()
var counter = 0
gameTimerLabel.text = String(counter)
gameTimerLabel.text = counter //<- Error:Cannot assign value to type 'Int' to type 'String?'
counter = date1.timeIntervalSinceDate(currentTime) //<- Error:Cannot assign value of type 'NSTimeInterval' (aka 'Double') to type 'Int'
}
A couple of things here
First, when you declare counter, it's inferred to be of type Int
var counter = 0
You can declare it as a double by adding a .0 or specifying it's type:
var counter: NSTimeInternval = 0.0
Next, you can use string interoperability to display the count variable in a string, like this:
gameTimerLabel.text = "\(counter)"
Here's an example view controller using an NSTimer as a counter, it counts in seconds:
class ViewController: UIViewController {
// Setup a timer and a counter for use
var timer = NSTimer()
var counter : NSTimeInterval = 0
#IBOutlet weak var label: UILabel!
// Invalidest the timer, resets the counter and udpates the label
#IBAction func resetTimer(sender: AnyObject) {
// Invalidate the timer, reset the label.
self.timer.invalidate()
self.label.text = ""
self.counter = 0
}
// A button that when pressed starts and stops the timer
// There's no pause/resume, so it's invalidated & created again
// But the counter value reamins the same
#IBAction func timerBttnTouched(sender: AnyObject) {
if self.timer.valid {
self.timer.invalidate()
} else {
self.setupTimer()
}
}
// Does the actual counting everytime the timer calls this method
func timerFired() {
self.counter += 1
self.label.text = "\(self.counter)"
}
// Setups a timer, adds it to the run loop and specifies what method should fire when the timer fires
func setupTimer() {
// Setupt the timer, this will call the timerFired method every second
self.timer = NSTimer(
timeInterval: 1,
target: self,
selector: #selector(self.timerFired),
userInfo: nil,
repeats: true)
// Add the timer to the run loop
NSRunLoop.currentRunLoop().addTimer(
self.timer,
forMode: NSDefaultRunLoopMode)
}
}
An important thing to note when using timers is they may not always be called exactly when you need them to, this should be taken into account according to your desired precision when using a timer.
As discussed in comments, here's the solution using a timer to fire a method that compares two dates and uses a NSDateComponentsFormatter to generate a string for display. The initial date is generated in viewDidLoad but can be created anywhere:
class ViewController: UIViewController {
// Setup a timer and a counter for use
var timer = NSTimer()
var counter : NSTimeInterval = 0
var startDate: NSDate?
override func viewDidLoad() {
// Set the initial date
self.startDate = NSDate()
}
#IBOutlet weak var label: UILabel!
// Invalidest the timer, resets the counter and udpates the label
#IBAction func resetTimer(sender: AnyObject) {
// Invalidate the timer, reset the label.
self.timer.invalidate()
self.label.text = ""
self.counter = 0
}
// A button that when pressed starts and stops the timer
// There's no pause/resume, so it's invalidated & created again
// But the counter value reamins the same
#IBAction func timerBttnTouched(sender: AnyObject) {
if self.timer.valid {
self.timer.invalidate()
} else {
self.setupTimer()
}
}
// Does the actual counting everytime the timer calls this method
func timerFired() {
let now = NSDate()
let difference = now.timeIntervalSinceDate(self.startDate!)
// Format the difference for display
// For example, minutes & seconds
let dateComponentsFormatter = NSDateComponentsFormatter()
dateComponentsFormatter.stringFromTimeInterval(difference)
self.label.text = dateComponentsFormatter.stringFromTimeInterval(difference)
}
// Setups a timer, adds it to the run loop and specifies what method should fire when the timer fires
func setupTimer() {
// Setupt the timer, this will call the timerFired method every second
self.timer = NSTimer(
timeInterval: 1,
target: self,
selector: #selector(self.timerFired),
userInfo: nil,
repeats: true)
// Add the timer to the run loop
NSRunLoop.currentRunLoop().addTimer(
self.timer,
forMode: NSDefaultRunLoopMode)
}
}
I am novice programmer =)
Help me please with random generator.
I would like to seed the random number generator so that it won't be the same every time.
func randomteTxt() {
var arr_person = [String]();
arr_person.append("ГЕНЕРАЛ");
arr_person.append("С КОЛБОЙ");
arr_person.append("ШПИОН");
arr_person.append("АРХИМЕД");
arr_person.append("ШЕКСПИР");
arr_person.append("С ФОНАРЕМ");
arr_person.append("БАРОН");
arr_person.append("ДИПЛОМАТ");
let time = UInt32(NSDate().timeIntervalSinceReferenceDate)
srand(time)
greatperson.text = arr_person[Int( random()%(arr_person.count))];
You can use NSTimer for that like add this in your viewDidLoad method:
var timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: Selector("randomteTxt"), userInfo: nil, repeats: true)
And you can invalidate it when you don't need it.
Just a simple task, but I'm in trouble. Trying to make a different way but it fails.
How to init NSTimer with declared previously variable? Neither var nor let helps.
The initial value of a property (in your case: timer) cannot depend on another property of the class (in your case: interval).
Therefore you have to move the assigment timer = NSTimer(interval, ...) into a method of the
class, e.g. into viewDidLoad. As a consequence, timer has to be defined as an
optional or implicitly unwrapped optional.
Note also that Selector(...) takes a literal string as argument, not the method itself.
So this should work:
class ViewController: UIViewController {
var interval : NSTimeInterval = 1.0
var timer : NSTimer!
func timerRedraw() {
}
override func viewDidLoad() {
super.viewDidLoad()
timer = NSTimer(timeInterval: interval, target: self, selector: Selector("timerRedraw"), userInfo: nil, repeats: true)
// ...
}
// Other methods ...
}
Try:
var interval:NSTimeInterval = 1.0
var timer = NSTimer.scheduledTimerWithTimeInterval(interval, target: self, selector: "timerRedraw:", userInfo: nil, repeats: true)
pro-tip and hopefully an appreciated FYI: Swift functions should also start with lower case letters (i.e. "timerRedraw").
Just a simple task, but I'm in trouble. Trying to make a different way but it fails.
How to init NSTimer with declared previously variable? Neither var nor let helps.
The initial value of a property (in your case: timer) cannot depend on another property of the class (in your case: interval).
Therefore you have to move the assigment timer = NSTimer(interval, ...) into a method of the
class, e.g. into viewDidLoad. As a consequence, timer has to be defined as an
optional or implicitly unwrapped optional.
Note also that Selector(...) takes a literal string as argument, not the method itself.
So this should work:
class ViewController: UIViewController {
var interval : NSTimeInterval = 1.0
var timer : NSTimer!
func timerRedraw() {
}
override func viewDidLoad() {
super.viewDidLoad()
timer = NSTimer(timeInterval: interval, target: self, selector: Selector("timerRedraw"), userInfo: nil, repeats: true)
// ...
}
// Other methods ...
}
Try:
var interval:NSTimeInterval = 1.0
var timer = NSTimer.scheduledTimerWithTimeInterval(interval, target: self, selector: "timerRedraw:", userInfo: nil, repeats: true)
pro-tip and hopefully an appreciated FYI: Swift functions should also start with lower case letters (i.e. "timerRedraw").