Keep updating NSTimer label after segue - ios

I have a number of initial settings in the viewDidLoad:
countDownLabel.alpha = 1
countDownLabel.text = "01:30"
swipeLeft.alpha = 0
swipeRight.alpha = 0
pressPlayToStartOr.alpha = 0
swipeToChangeTheSeq.alpha = 0
countDownPauseLbl.alpha = 0
I have an NSTimer (I've put func update () of the timer inside inside viewDidLoad as well, while it is triggered by a UIButton outside viewDidLoad). The timer continues running when I segue from the UI View Controller. When I segue back to the Timer View Controller, I can hear the sound of the timer running, but the Timer View Controller is refreshed to it's initial state and you can run the timer again so that they overlap. The programmatic segue after the timer finishes doesn't work in this case. I understand that I may have used the wrong approach, but hope it can be fixed. How can I make the label update, regardless of where I'am at in the app.

The effect:
In SingletonTimer.swift:
//
// SingletonTimer.swift
// testSwiftUITextField
//
// Created by leo on 2016/12/17.
// Copyright © 2016年 leo. All rights reserved.
//
import UIKit
class SingletonTimer: NSObject {
private static let sharedInstance = SingletonTimer()
class var sharedSingletonTimer:SingletonTimer {
return sharedInstance
}
var timeCount:Int = 100
func countDown() {
timeCount -= 1
timer_closure(timeCount)
}
lazy var timer:Timer = {
var timer:Timer
if #available(iOS 10.0, *) {
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { (timer) in
self.countDown()
})
} else {
// Fallback on earlier versions
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(countDown), userInfo: nil, repeats: true)
}
return timer
}()
var timer_closure:(Int)->Void = { (count) in
}
}
In ViewController.swift:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
}
In ViewController2.swift:
import UIKit
class ViewController2: UIViewController {
#IBOutlet weak var label: UILabel!
var timer:Timer? = nil
override func viewDidLoad() {
super.viewDidLoad()
timer = SingletonTimer.sharedSingletonTimer.timer
SingletonTimer.sharedSingletonTimer.timer_closure = { (timeCount) in
print("\(timeCount)")
self.label.text = "\(timeCount)s !"
}
if timer != nil {
timer?.fire()
}
}
}

Related

Time delay of texts in label in swift 3

I have a label. And I have 3 strings. I need to display text of 3 strings in the same label with delay of 10 seconds over a infinite loop. How can i solve this with simple animations in swift 3?
That's my solution. Just connect a UILabel to the IBOutlet
class ViewController: UIViewController {
#IBOutlet weak var textLabel: UILabel!
let messages = ["PROFESSIONAL AND BEST LEARNING CENTER","LEARNING TECHNOLOGY AND DESIGN IN A SMART WAY","EXPLORE YOUR SKILLS"]
let delayTime = 10.0
var counter = 0
override func viewDidLoad() {
super.viewDidLoad()
let timer = Timer.scheduledTimer(timeInterval: delayTime, target: self, selector: #selector(changeDisplayedText), userInfo: nil, repeats: true)
timer.fire()
}
func changeDisplayedText() {
textLabel.text = messages[counter % messages.count]
counter += 1
}
}
This will work for your, connect your outlet properly and declare those string in an array and load it with timer change.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var label: UILabel!
var array = ["Aaaaaaaaaaa", "Bbbbbbbbbbb", "Ccccccccccc"]
var scrollIndex = 0
override func viewDidLoad() {
super.viewDidLoad()
let timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(self.myDelayedFunction), userInfo: nil, repeats: true)
timer.fire()
}
func myDelayedFunction()-> Void {
let count = self.array.count
if scrollIndex == count {
scrollIndex = 0
}
if scrollIndex < count {
if count > 1{
self.label.text = array[scrollIndex]
self.scrollIndex += 1
}
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

NSTimer call function from superclass

Let's say I have a class Timer that works as a timer.
I want every other class that can act like a timer to have an attribute of type Timer.
The problem is: the Timer class uses a NSTimer attribute and I don't know how to associate functions from outside Timer in it.
For example: Class A has attribute B, which is Timer. How can scheduledTimerWithTimerInterval call some function of A?
Here is timer:
import UIKit
class Timer{
var interval: NSTimeInterval!
var counting: Bool = false
var numberOfTouches: Int = 0
private var timer: NSTimer = NSTimer()
init(interval: CGFloat){
self.interval = NSTimeInterval(interval)
self.counting = false
}
func Start(function: String) {
if(self.counting){
self.numberOfTouches += 1
self.timer.invalidate()
self.timer = NSTimer.scheduledTimerWithTimeInterval(self.interval, target: self, selector: Selector(function), userInfo: nil, repeats: false)
}
else{
self.counting = true
self.numberOfTouches = 1
}
}
func Stop(){
if(!self.counting){
self.counting = false
}
}
}
here is the ViewController:
import UIKit
class ViewController: UIViewController {
var timer: Timer = Timer(interval: 1.0)
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func Trigger(sender: AnyObject) {
//yes, this doesn't call t() from the ViewController
timer.Start("self.t")
}
func t(){
label.text = String(timer.numberOfTouches)
}
#IBOutlet weak var label: UILabel!
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Finally, what this timer tries to do is:
when I press the button, it starts counting and set the number of touches to 1;
if I press it again, less than 1 second after the touch before, it restart the 1 second timer and increases the touch by 1;
after 1 second without any touch, it should call t() from the ViewController to set the label to the last number of touches.
What approach should I use to fix this?
Thank you!
PS: in the beginning, it was Selector("Stop")
It's not "self.t", you supply the object as the target. The selector is something like "ViewController.t" or "t". You need to change Start to take a target object as well.
Move to Xcode 7.3.1 and use the new selector syntax if you can -- it will be type-checked.

Swift Run An NSTimer Automatically

I'm making an app and using NSTimer to make the timer in my app.But I need the NSTimer to run when the scene start.I have two scene in my app a homescreen and the app it's self here is my code viewcontroller.swift (The second scene the first scene in empty) And btw it's my 3 day using swift and i'm in middle school ;).
import UIKit
var Number = 2
var Answer = Number * 2
var score = 0
var scorelabel = "Score: "
var Timer = NSTimer()
var Counter = 10
class SecondViewController: UIViewController {
#IBOutlet weak var RightAndWrongLabel: UILabel!
#IBOutlet weak var TimerLabel: UILabel!
#IBOutlet weak var RightAndWrong: UIImageView!
#IBOutlet weak var ScoreIabel: UILabel!
#IBOutlet weak var UserInputAnswer: UITextField!
#IBOutlet weak var Question: UILabel!
#IBOutlet weak var TimerOut: UIImageView!
var seconds = 0
var timeison = true
#IBAction func ConfirmAnswer(sender: AnyObject) {
let UserAnswer = Int(UserInputAnswer.text!)
if UserAnswer == Answer {
print("Your right")
Number += 2
score += 1
ScoreIabel.text = "Score: \(score)"
Question.text = "\(Number) x 2"
UserInputAnswer.text = ""
Answer = Number * 2
RightAndWrong.image = UIImage(named: "Label")
RightAndWrongLabel.hidden = false
RightAndWrongLabel.text = "Right!"
RightAndWrongLabel.textColor = UIColor(red: 0, green: 225, blue: 0, alpha: 1)
} else {
UserInputAnswer.text = ""
RightAndWrong.image = UIImage(named: "Label")
RightAndWrongLabel.hidden = false
RightAndWrongLabel.text = "Wrong!"
RightAndWrongLabel.textColor = UIColor(red: 225, green: 0, blue: 0, alpha: 1)
}
}
func DisplayTimer() {
Timer = NSTimer.scheduledTimerWithTimeInterval(1, target:self, selector: Selector("updateCounter"), userInfo: nil, repeats: true)
}
func updateTimer(){
TimerLabel.text = String(Counter--)
}
override func viewDidLoad() {
super.viewDidLoad()
UserInputAnswer.keyboardType = UIKeyboardType.NumberPad
RightAndWrongLabel.hidden = true
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
3
// Dispose of any resources that can be recreated.
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
Swift 2.x :
func DisplayTimer() {
Timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target:self, selector: #selector(updateTimer), userInfo: nil, repeats: true)
}
func updateTimer() {
if Counter != 0 { TimerLabel.text = "\(Counter -= 1)"
} else {
Timer.invalidate()
// call a game over method here...
}
}
override func viewDidLoad() {
super.viewDidLoad()
...
// start the timer when this controller shows up
DisplayTimer()
TimerLabel.text = "\(Counter)"
...
}
If you want to start your timer when the scene loads call DisplayTimer() under
override func viewDidLoad() when the view is loaded
Also if you want to update your label every second, the selector in your NSTimer is calling updateCounter not updateTimer

How do you programmatically change view controllers?

underneath my timerVar.invalidate(), i want have another view controller called "SinglePlayerGameOver" loaded but i can't work out how.Basically, when the timerCount becomes bigger than 10, i want a "gameOver" screen to appear.
import Foundation
import UIKit
class SinglePlayer: UIViewController {
var timerCount = 0
#IBOutlet weak var timer: UILabel!
var timerVar = NSTimer()
var taps = 0
func isCounting() {
timerCount += 1
timer.text = "\(timerCount)"
if timerCount >= 10 {
timerVar.invalidate()
}
}
override func viewDidLoad() {
super.viewDidLoad()
timerVar = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "isCounting", userInfo: nil, repeats:true)
}
}
You can use this fuction
self.presentViewController(SinglePlayerGameOver, animated: true, completion: nil)
if u have navigationController, then
self.navigationController?.pushViewController(SinglePlayerGameOver, animated: true);
put this code after check the time is over 10

Simple swift Stopwatch don't work

This is my code.
//
// ViewController.swift
// Stopwatch
//
// Created by Orkun Atasoy on 12.09.15.
// Copyright (c) 2015 Orkun Atasoy. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var timerButton: UIButton!
var timer : NSTimer?
var ms = 0
#IBAction func buttonTapped(sender: AnyObject) {
timerButton.setTitle("Stopp", forState:UIControlState.Normal)
self.timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}
func update() {
self.ms++
timerLabel.text = String(self.ms)enter code here
}
}
The Problem is when i run the build it comes the introscreen with big text "Stopwatch" and the it is like freezed there. But it should come a label with button downside which has a text "start". When i click the button it should start counting and the label should change to "stopp". When i click again the it should stop the timer.
I dont get what the Problem ist. I am a Swift newbie. I would be pleased if you could help me.
Thank you for your attention
EDIT >> the label text is at the beginning "00:00".
Looks like you are messing with IBOutlet connections and I have corrected some of your code and here is working code:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var timerLabel: UILabel!
#IBOutlet weak var timerButton: UIButton!
var timer : NSTimer?
var ms = 0
override func viewDidLoad() {
timerLabel.text = "00:00"
}
#IBAction func buttonTapped(sender: AnyObject) {
if timerButton.currentTitle == "Stopp" {
timer?.invalidate()
timerButton.setTitle("Start", forState:UIControlState.Normal)
} else {
timerButton.setTitle("Stopp", forState:UIControlState.Normal)
self.timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}
}
func update() {
self.ms++
timerLabel.text = String(self.ms)
}
}
And First of all remove all outlets from your storyboard view controller and connect it this way:
And if you want check THIS sample project.
The method you call when the timer fires is incorrect. From the documentation:
The selector should have the following signature: timerFireMethod: (including a colon to indicate that the method takes an argument). The timer passes itself as the argument, thus the method would adopt the following pattern:
- (void)timerFireMethod:(NSTimer *)timer
So your method should be:
func update(timer: NSTimer) {
self.ms++
timerLabel.text = String(self.ms)
}
And you should set up your timer as:
NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "update:", userInfo: nil, repeats: true)
There are a few more things I could mention - such as no need to use self when unambigously using variables, and using a dispatch timer instead of an NSTimer, but this should at least solve your immediate problem.

Resources