How can I make a function execute every second in swift?
Solution 1
You can use one like this:
var timer = NSTimer()
override func viewDidLoad() {
scheduledTimerWithTimeInterval()
}
func scheduledTimerWithTimeInterval(){
// Scheduling timer to Call the function "updateCounting" with the interval of 1 seconds
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateCounting"), userInfo: nil, repeats: true)
}
func updateCounting(){
NSLog("counting..")
}
Swift 3:
var timer = Timer()
override func viewDidLoad() { // Use for the app's interface
scheduledTimerWithTimeInterval()
}
override func didMove(to view: SKView) { // As part of a game
scheduledTimerWithTimeInterval()
}
func scheduledTimerWithTimeInterval(){
// Scheduling timer to Call the function "updateCounting" with the interval of 1 seconds
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.updateCounting), userInfo: nil, repeats: true)
}
@objc func updateCounting(){
NSLog("counting..")
}
Swift 5:
Note: this solution is compatible with iOS 10.0+.
// If needing to check for iOS compatibility use
// if #available(iOS 10.0, *) {code}
var timer = Timer()
override func viewDidLoad() {
self.timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { _ in
updateCounting()
})
}
func updateCounting(){
print("counting...")
}
You can then invalidate (stop) the timer using:
timer.invalidate()
Solution 2
There is something called NSTimer in swift which could solve your problem. I have given an example like how you can use it. Just customise it for your purpose.
var timer = NSTimer.scheduledTimerWithTimeInterval(1.0,
target: self,
selector: Selector("yourMethodToCall"),
userInfo: nil,
repeats: true)
Add this line to the place where you need to call your function repeatedly.
- The
1.0
refers to 1 second. - Change the
selector
to call yourMethodName -
repeats
is set totrue
to call that function every second.
Try this out and let me know if your are stuck somewhere. Thanks.
Solution 3
Swift 3
find this solution it worked for me
weak var timer: Timer?
var timerDispatchSourceTimer : DispatchSourceTimer?
func startTimer() {
if #available(iOS 10.0, *) {
timer = Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { [weak self] _ in
// do something here
}
} else {
// Fallback on earlier versions
timerDispatchSourceTimer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.main)
timerDispatchSourceTimer?.scheduleRepeating(deadline: .now(), interval: .seconds(60))
timerDispatchSourceTimer?.setEventHandler{
// do something here
}
timerDispatchSourceTimer?.resume()
}
}
func stopTimer() {
timer?.invalidate()
//timerDispatchSourceTimer?.suspend() // if you want to suspend timer
timerDispatchSourceTimer?.cancel()
}
// if appropriate, make sure to stop your timer in `deinit`
deinit {
stopTimer()
}
Solution 4
I prefer
var timer: Timer?
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer) in
// Do what you need to do repeatedly
}
}
To stop it:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if timer != nil {
timer?.invalidate()
timer = nil
}
}
Solution 5
Xcode 10.2 Swift 5:
override func viewDidLoad() {
super.viewDidLoad()
// ...
Timer.scheduledTimer(timeInterval: 8.0, target: self, selector: Selector(("your @obcj func name")), userInfo: nil, repeats: true)
}
//Anywhere in the same view controller to stop the loop:
Timer.cancelPreviousPerformRequests(withTarget: your @obcj func name())
Ryan Allen
Updated on October 16, 2021Comments
-
Ryan Allen over 2 years
I want to add a score to the top of my scene in the game I am working on. The score is going to based on how long you last, and will increase every second. Thanks for the help in advance!
import SpriteKit class easyScene: SKScene { let scrollBarEasyBottom = SKSpriteNode(imageNamed: "scrollBarEasyBottom") let scrollBarEasyTop = SKSpriteNode(imageNamed: "scrollBarEasyTop") let ball = SKSpriteNode(imageNamed: "ball") var origSBEBpositionX = CGFloat(0) var origSBETpositionX = CGFloat(0) var maxSBEBX = CGFloat(0) var SBEBSpeed = 5 var maxSBETX = CGFloat(0) var SBETSpeed = 5 var score = 0 var timer: NSTimer? var scoreText = SKLabelNode(fontNamed: "Kailasa") override func didMoveToView(view: SKView) { println("Easy Scene is the location") self.backgroundColor = UIColor.blackColor() self.scrollBarEasyBottom.position = CGPoint(x:0, y:270) self.addChild(self.scrollBarEasyBottom) self.scrollBarEasyBottom.yScale = 0.2 self.origSBEBpositionX = self.scrollBarEasyBottom.position.x // end scrollBarEasyBottom self.scrollBarEasyTop.position = CGPoint(x:20, y:400) self.addChild(self.scrollBarEasyTop) self.scrollBarEasyTop.yScale = 0.2 self.origSBETpositionX = self.scrollBarEasyTop.position.x // end scrollBarEasyTop self.ball.position = CGPoint(x:40, y:293) self.addChild(self.ball) self.ball.yScale = 0.17 self.ball.xScale = 0.17 // end ball self.maxSBEBX = self.scrollBarEasyBottom.size.width - self.frame.size.width self.maxSBEBX *= -1 self.maxSBETX = self.scrollBarEasyTop.size.width - self.frame.size.width self.maxSBETX *= -1 // self.scoreText.text = "0" self.scoreText.fontSize = 60 self.scoreText.position = CGPoint(x: CGRectGetMidX(self.frame), y: 500) self.scoreText.text = String(self.score) self.addChild(self.scoreText) timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("scoreIncrease") , userInfo: nil, repeats: true) func scoreIncrease (){ score++ println(score) } } override func update(currentTime: NSTimeInterval) { if self.scrollBarEasyBottom.position.x <= maxSBEBX + 1200 { self.scrollBarEasyBottom.position.x = self.origSBEBpositionX } if self.scrollBarEasyTop.position.x <= maxSBETX + 1200 { self.scrollBarEasyTop.position.x = self.origSBETpositionX } scrollBarEasyBottom.position.x -= CGFloat(self.SBEBSpeed) scrollBarEasyTop.position.x -= CGFloat(self.SBETSpeed) // moving bars var degreeRotation = CDouble(self.SBEBSpeed) * M_PI / 180 self.ball.zRotation -= CGFloat(degreeRotation) //rotate ball } }
After running this code, I always get an
unrecognized selector sent to instance error