Swift 2.2 - NSTimer with optional completion-handler selector - swift2

I am trying to call a function with optional CompletionHandler parameter from a timer. Below is my code snippet:
typealias CompletionHandler = () -> Void
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(ViewController.check(_:)), userInfo: nil, repeats: false)
}
func check(completion: CompletionHandler?) {
print("userinfo1")
}
}
When the timer is triggered after 1.0 second, my app is dead with EXC_BAD_ACCESS and the pointer points to class AppDelegate: UIResponder, UIApplicationDelegate in AppDelegate.
Can you show me how I can call check function with such parameter? (If completion is just an Int, the timer did work!)
Thanks

You can create a timer like this:
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: #selector(connectionTimeoutExpired(_:)), userInfo: nil, repeats: false)
func connectionTimeoutExpired(sender: NSTimer) {
print("Connection Timeout Expired")
connectionTimer?.invalidate()
connectionTimer = nil
}

Related

Xcode - control drag function not working

Beneath is my code,
Currently, it isn't working and allowing me to connect a button to my swift file (main storyboard). Also, the timer function isn't working, would this be to do with the function not working as well?
unsure on how to fix this, let me know if you need any other screen shots.
Any help will be appreciated.
Thanks
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var CounterLabel: UILabel!
var time = 30
var timer = Timer()
#IBAction func start(_ sender: UIButton)
{
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.action), userInfo: nil, repeats: true)
}
func action()
{
time += 1
}
//GIFS
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.
}
}

Issues with NSNotificationCenter in #IBAction function

I am working on an app that requires my main view controller to receive notifications from its child view controller. To do this, I set up the observer in the viewDidLoad() method of the parent controller, and I am trying to call the postNotificationName() function when a button is pressed that is located in the child view controller.
When the postNotificationName() call is located in the #IBAction func buttonPressed(){ } function, the observer never gets the notification. However, when the same code is called from a different function in the same view controller, it works.
I thought this might be a thread issue, and unsuccessfully tried many of the solutions for that issue. I'm not very familiar with threading, though, so maybe I still missed it. Does anyone have any idea what the issue might be?
Thanks for the help!
ViewController
class GameController: UIViewController {
override func viewDidLoad() {
super.init()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "attemptHumanMove:", name: Constants.NSNotificationKey.tilePressed, object: nil)
}
func attemptHumanMove(notification: NSNotification) {
print("test")
}
ChildViewController
#IBAction func tileTouched(sender: AnyObject) {
NSNotificationCenter.defaultCenter().postNotificationName(Constants.NSNotificationKey.tilePressed, object: nil, userInfo: ["a": 0])
}
Experimenting with the flow you have mentioned, the following code does receive the notification message from a child view controller.
ParentViewController
class ViewController: UIViewController {
#IBOutlet weak var notificationMsgLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
notificationMsgLabel.text = "Waiting for notification..."
NSNotificationCenter.defaultCenter().addObserver(self, selector: "attemptHumanMove:", name: "tilePressed", object: nil)
}
func attemptHumanMove(notification: NSNotification) {
print("Notification message received!")
notificationMsgLabel.text = "Notification received!!!"
}
}
ChildViewController
class ChildViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func sendNotification() {
print("Sending notification message!!!")
NSNotificationCenter.defaultCenter().postNotificationName("tilePressed", object: nil, userInfo: ["a": 0])
}
}
Here you can find the screen shot of the storyboard:
Storyboard Snapshot

Swift NSTimer Coding

Using Swift 2.0 and trying to implement Swift NSTimer in Custom Keyboard. Button2 shows up great when Button1 is pressed, until the NSTimer kicks in and crashes the keyboard.
I'm trying to hide Button2 after a few seconds.
#IBAction func Button1(sender: UIButton) {
Button2.setTitle("Text", forState: UIControlState.Normal)
NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("Hide:"), userInfo: nil, repeats: false)
Button2.hidden = false
}
This should work (note that I changed some of the function names to more closely follow conventions):
#IBAction func button1Tapped() {
button2.setTitle("Text", forState: .Normal)
button2.hidden = false
NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "hideButton2", userInfo: nil, repeats: false)
}
#objc func hideButton2() {
button2.hidden = true
}
Replace Selector("Hide:") with "Hide:" and add #objc in front of your func

Extra argument 'selector' in call

I'm trying to create a simple stopwatch app where the timer label increments when the startButton button is pressed. This is what I have:
#IBOutlet weak var timer: UILabel!
#IBAction func startButton(sender: AnyObject) {
timer = NSTimer.scheduledTimerWithTimeInterval(0.0025, target: self, selector: Selector("result"), userInfo: nil, repeats: true)
}
var count = 0
func result() {
count++
timer.text=String(count)
}
I get the error "Extra argument 'selector' in call" but can't workout the syntax to do it properly.
Swift error messages are a little lacking at times. It should have said something like "NSTimer is not convertible to UILabel". You are assigning the timer you create to your IBOutlet timer which is a UILabel. The timer is an NSTimer. Just assign it to a different variable when you create it and all will be fine.
#IBAction func startButton(sender: AnyObject) {
let myTimer = NSTimer.scheduledTimerWithTimeInterval(0.0025, target: self, selector: "result", userInfo: nil, repeats: true)
}
As a shortcut, you can just use a string as a selector, so Selector("result") can be replaced by just "result".

Change label.text from function Xcode/Swift

I have a timer, which calls a selector.
Directly from that function, I want to change the text of a label.
#IBOutlet weak var myLabel: UILabel!
override func viewDidLoad() {
var timer = NSTimer.scheduledTimerWithTimeInterval(0.4, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}
func update () {
self.myLabel.text = "MyNewText"
}
Xcode tells me to use "self", but the label is still not updating!
Thanks for your help!
UI updates must always be done in the main thread, so try this:
func update () {
DispatchQueue.main.async {
self.myLabel.text = "MyNewText"
}
}

Resources