I need launch the timer few times in sequence (one after another). And of course I need update Label with timer results.
For example, I have two periods (50 sec and 10 sec) and I need to make a series of periods: 50-10-50-10-50-10.
How can I do it?
import UIKit
class StartTimerViewController: UIViewController {
let firstPeriodTime = 50
let secondPeriodTime = 10
var currentPeriodTime: Int!
let repetitionTime = 3
var timer: NSTimer!
var timeCount = 0
#IBOutlet weak var timerLabel: UILabel!
// MARK: - IBAction method implementation
#IBAction func start(sender: AnyObject) {
// I know it's wrong... This is my question!!!!!
var i = 1
while i <= repetitionTime {
currentPeriodTime = firstPeriodTime
startTimer()
currentPeriodTime = secondPeriodTime
startTimer()
i = i + 1
}
}
// MARK: - Timer method implementation
func startTimer() {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector: "updateCounter", userInfo: nil, repeats: true)
print("timer start")
}
func updateCounter() {
if timeCount < currentPeriodTime {
timeCount++
let currentTime = Double(currentPeriodTime - timeCount)
timerLabel.text = timeString(currentTime)
}
else {
timer.invalidate()
timeCount = 0
}
}
func timeString(time:NSTimeInterval) -> String {
let minutes = Int(time) / 60
let seconds = time - Double(minutes) * 60
return String(format:"%02i:%02i",minutes,Int(seconds))
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Please use the code below
#IBOutlet weak var _lblTimer: UILabel!
var timer = NSTimer()
var intValue = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update50:", userInfo: nil, repeats: true)
}
func update50(timer : NSTimer){
intValue += 1
_lblTimer.text = intValue.description
if(intValue == 50){
intValue = 0
timer.invalidate()
self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update10:", userInfo: nil, repeats: true)
}
}
func update10(timer : NSTimer){
intValue += 1
_lblTimer.text = intValue.description
if(intValue == 10){
intValue = 0
timer.invalidate()
self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "update50:", userInfo: nil, repeats: true)
}
}
Related
I want to set a timer of 30 seconds to send an OTP to a phone number. And while the timer is running, the resend OTP button should be disabled. Once the timer ends, the resend OTP button should get enabled and the timer label should be hidden. Onclick of the resend OTP button, the same process should continue.
In the code that I have written, the timer label is hidden the entire time and is constantly going into the if loop where it is constantly printing "invalidated".
Below is the code that I have written.
Updated Code:
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var resendOTPBtn: UIButton!
var countdownTimer: Timer!
var totalTime = 30
override func viewDidLoad() {
super.viewDidLoad()
if AFWrapper.isConnectedToInternet() {
timerLabel.text = ""
sendOTPCode()
sendOTPAPICall()
resendOTPBtn.isEnabled = false
} else {
self.textPopupAlert(title: ALERT_TITLE, message: OFFLINE_MSG)
}
}
// in case user closed the controller
deinit {
countdownTimer.invalidate()
}
#objc func updateTimerLabel() {
totalTime -= 1
timerLabel.text = "\(timeFormatted(totalTime))"
if totalTime == 0 {
timerLabel.text = ""
countdownTimer.invalidate()
resendOTPBtn.isEnabled = true
}
}
#IBAction func resendOTPBtnClicked(_ sender: Any) {
if AFWrapper.isConnectedToInternet() {
sendOTPAPICall()
timerLabel.text = ""
totalTime = 31
resendOTPBtn.isEnabled = false
sendOTPCode()
}
else {
self.textPopupAlert(title: ALERT_TITLE, message: OFFLINE_MSG)
}
}
func sendOTPCode() {
self.countdownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.updateTimerLabel), userInfo: nil, repeats: true)
}
Initial Code:
#IBAction func resendOTPBtnClicked(_ sender: Any) {
if AFWrapper.isConnectedToInternet() {
sendOTPAPICall()
countDownTime()
}
else {
self.textPopupAlert(title: ALERT_TITLE, message: OFFLINE_MSG)
}
}
func countDownTime() {
DispatchQueue.main.asyncAfter(deadline: .now() + 60) {
self.timerLabel.isHidden = false
self.resendOTPBtn.isEnabled = false
if self.timerLabel.isHidden == false {
self.startTimer()
} else {
self.countdownTimer.invalidate()
self.resendOTPBtn.isEnabled = true
self.timerLabel.isHidden = true
}
}
}
// Method to start the timer when resend OTP button is clicked.
func startTimer() {
countdownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
}
#objc func updateTime() {
DispatchQueue.main.async(){
self.timerLabel.text = self.timeFormatted(self.totalTime)
if self.totalTime != 0 {
self.totalTime -= 1
} else {
print("Invalidated")
self.endTimer()
}
}
}
func timeFormatted(_ totalSeconds: Int) -> String {
let seconds: Int = totalSeconds % 60
let minutes: Int = (totalSeconds / 60) % 60
// let hours: Int = totalSeconds / 3600
return String(format: "%02d:%02d", minutes, seconds)
}
Any solutions would be appreciated. Thank you!
#IBOutlet weak var resendCodeTimerLabel: UILabel!
#IBOutlet weak var resendCodeButton: UIButton!
var resendCodeCounter = 30
var resendCodeTimer = Timer()
override func viewDidLoad() {
super.viewDidLoad()
resendCodeTimerLabel.text = ""
sendOTPCode()
}
// in case user closed the controller
deinit {
resendCodeTimer.invalidate()
}
#objc func updateTimerLabel() {
resendCodeCounter -= 1
resendCodeTimerLabel.text = "Resend code in \(resendCodeCounter) seconds."
if resendCodeCounter == 0 {
resendCodeButton.isEnabled = true
resendCodeTimer.invalidate()
}
}
#IBAction func resendAgainButtonClicked(_ sender: UIButton) {
OTPTextField.text = ""
resendCodeCounter = 31
resendCodeButton.isEnabled = false
sendOTPCode()
}
func sendOTPCode() {
//Whatever your api logic
if otpSent {
self.resendCodeTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self.updateTimerLabel), userInfo: nil, repeats: true)
}
}
I'm trying to get output like so:
1 (then a one second delay)
Hello
2 (then a one second delay)
Hello
3 (then a one second delay)
Hello
But instead I get
1
2
3 (then a one second delay)
Hello
Hello
Hello
Here's my for loop invoking the NSTimer
var timer = NSTimer()
for i in 1...3 {
print("\(i)");
timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(MainVPScreenViewController.printTest), userInfo: nil, repeats: false)
}
And here's the selector method:
func printTest() {
print("Hello")
}
Thanks in advance for any help you can provide
Try this solution without NSTimer:
var i = 1
func printHello() {
print(i)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) {
print("Hello")
i +=1
if i <= 3 {
printHello()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
printHello()
}
I need 2 NSTimers to do this, this is my approach
class ViewController: UIViewController {
var i = 1
override func viewDidLoad() {
super.viewDidLoad()
beginPrinting()
}
func beginPrinting() {
var timer2 = NSTimer()
if(i <= 100)
{
timer2 = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(self.printWithDelay), userInfo: nil, repeats: false)
}
}
func printWithDelay()
{
var timer = NSTimer()
print("\(i)");
i += 1
timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(self.printTest), userInfo: nil, repeats: false)
}
func printTest() {
print("Hello")
beginPrinting()
}
}
Hope this helps you
Use timer with repeat to true. So in your view controller would be like this
var timer = NSTimer()
var counter = 0
var max = 10
let delay = 1 // in second
override func viewDidLoad() {
super.viewDidLoad()
timer = NSTimer.scheduledTimerWithTimeInterval(delay, target: self,
selector: #selector(self.printTest), userInfo: nil, repeats: true)
}
func printTest() {
counter += 1
print(counter)
print(hello)
if counter == maxNumber {
timer.invalidate()
}
}
This does it with repeat false, and is set up to be in a playground:
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
#objc class Foo: NSObject {
static var timer = NSTimer()
var i:Int
override init() {
Foo.timer = NSTimer()
i = 1
}
func schedule() {
print("\n\(i)");
i += 1
Foo.timer = NSTimer.scheduledTimerWithTimeInterval(1.0,
target: self,
selector: #selector(printTest),
userInfo: nil,
repeats: false)
}
#objc func printTest() {
print("Hello")
if i < 5 {
schedule()
}
}
}
let bar = Foo()
bar.schedule()
I am attempting to make a countdown timer that counts down from 60 seconds and then stops when it gets to 0. But for the timer keeps going into negative seconds. Any advice is appreciated. Code:
#IBOutlet var timeCounter: UILabel!
var second = 60
var timer = NSTimer()
var timerRunning = true
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
setTimer()
timerCounting()
}
func setTimer(){
second -= 1
timeCounter.text = "\(second)"
}
func timerCounting(){
if(timerRunning == true){
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("setTimer"), userInfo: nil, repeats: true)
timerRunning = true
if second == 0 {
timerRunning = false
timer.invalidate()
}
}
}
You have to move the invalidation into the setTimer function since at its current location will never be triggered because timerCounting is only called once - in the beginning.
func setTimer(){
second -= 1
timeCounter.text = "\(second)"
if second == 0 {
timerRunning = false
timer.invalidate()
}
}
play with this in playground
import XCPlayground
XCPlaygroundPage.currentPage.needsIndefiniteExecution = true
import Foundation
#objc class C:NSObject {
var timer: NSTimer?
var second = 5
func setTimer(){
if c.second < 0 {
print("the timer fires the last time here ...")
timer?.invalidate()
} else {
print(second)
second -= 1
}
}
}
let c = C()
func timerCounting(){
c.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: c, selector: Selector("setTimer"), userInfo: nil, repeats: true)
}
timerCounting()
I made a stopwatch in swift. It has three buttons- play, stop, reset. it has a display in the middle where I display the seconds passed.
My code runs fine. But the watch runs very fast after the stop or reset.
I am not able to figure out what is the fuss.
please help!
var time = 0
var timer = NSTimer()
var pause = Bool(false)
#IBOutlet var result: UILabel!
func displayResult() {
if pause != true
{
time++
result.text = String(time)
}
}
#IBAction func reset(sender: AnyObject) {
time = 0
result.text = String(time)
}
#IBAction func pause(sender: AnyObject) {
pause = true
}
#IBAction func play(sender: AnyObject) {
pause = false
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("displayResult") , userInfo: nil, repeats: true)
}
Your pause action should be:
#IBAction func pause(sender: AnyObject) {
timer.invalidate()
pause = true
}
UPD:
var time = 0
var timer = NSTimer()
var pause = true // 1
func displayResult() {
if pause != true
{
time++
label.text = String(time)
}
}
#IBAction func reset(sender: AnyObject) {
time = 0
label.text = String(time)
timer.invalidate() // 2
pause = true // 3
}
#IBAction func pause(sender: AnyObject) {
timer.invalidate() // 4
pause = true
}
#IBAction func play(sender: AnyObject) {
// 5
if pause == true {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("displayResult") , userInfo: nil, repeats: true)
pause = false
}
}
My game is supposed to be stopped after 60s. But nothing happens with my timer code.
var timer = NSTimer()
var counter:Int = 60
var labelCounter:SKLabelNode = SKLabelNode()
Here is the code in my GameScene class :
func startTimer()
{
timer = NSTimer.scheduledTimerWithTimeInterval(1.0
, target: self, selector: Selector("updateTimer:"), userInfo: nil, repeats: true)
}
func updateTimer(dt:NSTimer)
{
counter--
if counter == 0 {
timer.invalidate()
removeCountDownTimerView()
} else{
labelCounter.text = "\(counter)"
}
}
func removeCountDownTimerView()
{
scene.view.paused = true
}
thank you for your insight :-)
Try something like this....
override func viewDidLoad() {
super.viewDidLoad()
//calling the wait function
self.callForWait()
}
func callForWait(){
//setting the delay time 60secs.
let delay = 60 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
dispatch_after(time, dispatch_get_main_queue()) {
//call the method which have the steps after delay.
self.stepsAfterDelay()
}
}
func stepsAfterDelay(){
//your code after delay takes place here...
}
I had this in a game. Hope it helps:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
startGame()
}
var startTime = NSTimeInterval()
var timer = NSTimer()
var gameTime:Double = 10
func startGame() {
let aSelector : Selector = "updateTime"
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: aSelector, userInfo: nil, repeats: true)
startTime = NSDate.timeIntervalSinceReferenceDate()
}
func updateTime() {
var currentTime = NSDate.timeIntervalSinceReferenceDate()
var elapsedTime = currentTime - startTime
var seconds = gameTime-elapsedTime
if seconds > 0 {
elapsedTime -= NSTimeInterval(seconds)
println("\(Int(seconds))")
} else {
timer.invalidate()
}
}
}