Timer function crashes app - swift

import UIKit
class ViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
var timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(ViewController.runTimedCode), userInfo: nil, repeats: true)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#objc func runTimedCode() {
imageView.image = UIImage(named: "card10")
}
}
This code gives me the message "unrecognized selector sent to instance" but i do not know what the problem is. Can someone please help me? :)

Try this instead:
class ViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
var timer: Timer? = nil
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(ViewController.runTimedCode), userInfo: nil, repeats: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#objc func runTimedCode() {
imageView.image = UIImage(named: "card10")
}
}

you have to call the function like bellow.
var timer:Timer?
override func viewDidLoad(){
super.viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.runTimedCode), userInfo: nil, repeats: true)
}
#objc func runTimedCode(){
print("timer is calling")
}

Related

Timer class, not increasing count

I'm not sure where I did wrong. I don't see any error, but the count isn't increasing.
#IBOutlet weak var myTimerLabel: UILabel!
let myTimer = Timer()
#objc func myTestFunc() {
var count = 0
count+=1
myTimerLabel.text = String(count)
}
override func viewDidLoad() {
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector
(myTestFunc), userInfo: nil, repeats: true)
}
Its not increasing because each time myTestFunc() called, it reinitialize the count variable with zero. So, declare count variable outside myTestFunc().
You have to make structure in right way
check this:
#IBOutlet weak var myTimerLabel: UILabel!
let myTimer = Timer()
var count = 0
//MARK: - view did load
override func viewDidLoad() {
Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector (myTestFunc), userInfo: nil, repeats: true)
}
//TODO:- here implement your funtion
#objc func myTestFunc() {
count+=1
myTimerLabel.text = String(count)
// if you want to stop your timer
myTimer.invalidate()
}
Good luck

swift how to update first controller from logic in second one vai protocol and delegate pattern?

I have a label in first view controller ViewController, and a func getting date avery second in second vc. I'd like to update label in first after timer starts in second. is it good to use protocol-delegate pattern? at this moment it is not working, time is going but not updating the view in first VC
my struct for protocol
protocol ViewControllerDelegate: class {
func changeLabelText(textToPass: String)
}
in first viewController
class ViewController: UIViewController, ViewControllerDelegate {
#IBOutlet weak var mainLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
}
func changeLabelText(textToPass: String) {
self.mainLabel.text = textToPass
self.view.layoutIfNeeded()
}
#IBAction func buttonTapped(_ sender: UIButton) {
let nextVC = storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
nextVC.delegateSubscriber = self
present(nextVC, animated: true, completion: nil)
}
}
in secondVC
class SecondViewController: UIViewController {
//MARK: speed timer feature 1/3
private weak var timer: Timer?
private var timerDispatchSourceTimer : DispatchSourceTimer?
weak var delegateSubscriber : ViewControllerDelegate?
#IBOutlet weak var myTxtField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
startTimer(every: 1)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("appeared")
stopTimer()
}
private func startTimer(every timeInterval: TimeInterval) {
if #available(iOS 10.0, *) {
timer = Timer.scheduledTimer(withTimeInterval: timeInterval, repeats: true) { [weak self] _ in
let dateToPass = Date().description
print(dateToPass)
self?.delegateSubscriber?.changeLabelText(textToPass: dateToPass)
}
}
}
//MARK: speed timer feature 3/3
private func stopTimer() {
timer?.invalidate()
//timerDispatchSourceTimer?.suspend() // if you want to suspend timer
timerDispatchSourceTimer?.cancel()
}
#IBAction func buttonTapped(_ sender: UIButton) {
// delegateSubscriber?.changeLabelText(textToPass: self.myTxtField.text ?? "error")
dismiss(animated: true, completion: nil)
}
}
Just remove [weak self] from Timer closure
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
let dateToPass = Date().description
print(dateToPass)
self.delegateSubscriber?.changeLabelText(textToPass: dateToPass)
}
... then self isn't optional

NSTimer() - timer.invalidate not working on a simple stopwatch?

I'm kind of at a wall of what to do, the program runs, but the timer.invalidate() does not work? Any tips are welcome.
I worked with this program in the past and worked through it and the timer.invalidate() worked flawlessly. I do not believe that it has to do with the fact that I put it into a function because before it wasn't working when I was just typing "timer.invalidate()" instead of "stop()"
Whenever I click the button Cancel on the iOS simulator it just resets it back to 0, but keeps counting.
Thanks in advance.
import UIKit
class ViewController: UIViewController {
var timer = NSTimer()
var count = 0
#IBOutlet weak var timeDisplay: UILabel!
#IBAction func playButton(sender: AnyObject) {
//play button
var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("result"), userInfo: nil, repeats: true)
}
#IBAction func resetTimer(sender: AnyObject) {
//cancel button
stop()
count = 0
timeDisplay.text = "0"
}
#IBAction func pauseButton(sender: AnyObject) {
stop()
}
func result() {
count++
timeDisplay.text = String(count)
}
func stop () {
timer.invalidate()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
In playButton() you are defining another timer, that can't be invalidated from outside this function - so by calling timer.invalidate() you invalidate just var timer = NSTimer() which doesn't carry any set timer in it.
So replace
var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("result"), userInfo: nil, repeats: true)
with
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("result"), userInfo: nil, repeats: true)

NSTimer hangs program after firing

I am creating a timer inside my ViewController. After it fires once, the program ceases to respond to any further UI events.
I create the timer inside of ViewDidLoad() with:
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "initTimerFired", userInfo: nil, repeats: false)
with timer function (defined as method of ViewController):
func initTimerFired(){
println("Timer fired")
}
It successfully fires, but thereafter the program hangs and does not respond to UI events. If I set repeat = true then it runs a couple of times before quitting with EXC_BAD_ACCESS.
I have looked at many different answers and examples, and I can't see what I am doing wrong.
I am running this on an iOS simulator, using xcode 6.1.
Here is an update. Thanks to the suggestions and code provided in the first answer, I have something working. However, my code, which looks to me to be the same, does not work. In order to implement things within the context of a larger project, I want to know how to avoid the errors I am seeing. For instance, this works:
class ViewController: UIViewController {
#IBOutlet weak var strConsole: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
initTaskManager()
}
func initTaskManager(){
let taskManager = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "updateTask", userInfo: nil, repeats: true)
}
func updateTask(){
self.strConsole.text = "\(strConsole.text!)Abc"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
But this version does not. Only the function names have changed!:
class ViewController: UIViewController {
#IBOutlet weak var strConsole: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
initTimer()
}
func initTimer(){
let timer1 = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "initTimerFired", userInfo: nil, repeats: true)
}
func initTimerFired(){
self.strConsole.text = "\(strConsole.text!)Abc"
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Do not use: initTimerFired, change to something else like: handleTimer,
init as a prefix of the function name may confuse Xcode
See here:
https://developer.apple.com/library/ios/documentation/swift/conceptual/buildingcocoaapps/InteractingWithObjective-CAPIs.html
you have to do like this:
import UIKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet weak var strConsole: UILabel!
func startTaskManager(){
let taskManager = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "updateTask", userInfo: nil, repeats: true)
}
func updateTask(){
self.strConsole.text = "\(strConsole.text!)Abc"
}
override func viewDidLoad() {
super.viewDidLoad()
startTaskManager()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}

Could not find an overload for “init” that accepts the supplied arguments (swift)

It worked in swift beta4 and now i have GM version
but this error says hello
how can i solve this problem?
"Could not find an overload for 'init' that accepts the supplied arguments" in 2 parts
var timer = NSTimer()
var counter : Double = 7.0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
labelCounter.text = String(counter) <- error here
}
#IBOutlet weak var labelCounter: UILabel!
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func startCounterPressed(sender: AnyObject) {
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}
func update() {
sth cool
}
#IBAction func pauseCounterPressed(sender: AnyObject) {
timer.invalidate()
}
#IBAction func stopCounterPressed(sender: AnyObject) {
timer.invalidate()
counter = 7.0
labelCounter.text = String(counter) <- error here
String class overload init method for double.
let s = NSString(format: "%.2f", counter)