notification firing 6 times a minute (swift4) - ios

Every time my notification timer goes off it repeats 6 times via in the minute. I only want the notification to fire once per minute. How can I write the code so the notification only goes off once per minute.
import UIKit
class ViewController: UIViewController {
var timer = Timer()
var passingDate : Date?
#IBOutlet var dptext: UITextField!
let datePicker = UIDatePicker()
override func viewDidLoad() {
createDatePicker()
timer = Timer.scheduledTimer(timeInterval: 10, target: self, selector: #selector(ViewController.testDate), userInfo: nil, repeats: true)
}
func createDatePicker() {
datePicker.datePickerMode = .dateAndTime
let toolbar = UIToolbar()
toolbar.sizeToFit()
let doneButton = UIBarButtonItem(barButtonSystemItem: .done, target: nil, action: #selector(donePressed))
toolbar.setItems([doneButton], animated: false)
dptext.inputAccessoryView = toolbar
dptext.inputView = datePicker
}
#objc func testDate() {
if Calendar.current.isDate(datePicker.date, equalTo: Date(), toGranularity: .minute) {
print("success")
if let passingDate = passingDate, Calendar.current.isDate(datePicker.date, equalTo: passingDate, toGranularity: .minute) {
// Previous date existing, and is in the same minute as the current date : do nothing
return
}
passingDate = datePicker.date
print("success")
}
}
#objc func donePressed() {
let dateFormatter = DateFormatter()
dateFormatter.dateStyle = .short
dateFormatter.timeStyle = .short
dptext.text = dateFormatter.string(from: datePicker.date)
self.view.endEditing(true)
}
}

Change the timeInterval from 10 to 60 :
timer = Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(ViewController.testDate), userInfo: nil, repeats: true)

Related

How do I fix this code to allow for the timer to begin as a result of the user clicking on the UIAlert?

Trying to make a timer start as a result of the UIAlert being clicked on. But I keep getting this error indicating the instances isTimerRunning and runTimer cannot be used on the thirdViewController.
We have been trying to move it around, thinking it is a scope issue, but cannot seem to get it to be ok with those functions.
When we adjusted it to use alert.copyAction, rather than let.. the error changes to "expected declaration".
var seconds = 60
var timer = Timer()
var isTimerRunning = false
var resumeTapped = false
let alert = UIAlertController(title: "Your wing was damaged! There is also a dust storm incoming! You need to repair the wing and escape to the next planet.", message: nil, preferredStyle: .alert)
let copyAction = UIAlertAction(title: "Copy that mission control!", style: .default, handler: { action in
if isTimerRunning == false {
runTimer()
}
})
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(thirdViewController.updateTimer)), userInfo: nil, repeats: true)
}
#objc func updateTimer() {
if seconds < 1 {
timer.invalidate()
} else {
seconds -= 1
timeLabel.text = timeString(time: TimeInterval(seconds))
}
}
func timeString(time:TimeInterval) -> String {
let hours = Int(time) / 3600
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format:"%02i:%02i:%02i”, hours, minutes, seconds")
}
override func viewDidLoad() {
super.viewDidLoad()
Timer.scheduledTimer(withTimeInterval: 0.0, repeats: false) { (timer) in
self.alert.addAction(self.copyAction)
self.present(self.alert,animated: true, completion: nil)
}
}
//use run timer method in alert controller).so you can start timer with open alert
override func viewDidLoad() {
super.viewDidLoad()
Timer.scheduledTimer(withTimeInterval: 0.0, repeats: false) { (timer) in
runtimer()
self.alert.addAction(self.copyAction)
self.present(self.alert,animated: true, completion: nil)
}
}

Getting : "Attempt to dismiss from view controller while a presentation or dismiss is in progress"

A Swift 4 quiz app.
First view - select num of questions to solve. (use segue to second view)
Second view - start quiz ->checked answer and send "correct" or "wrong" msg to third view. (use segue way to third view)
When the third view appears I get the error:
Attempt to dismiss from view controller <XXX.StartQuizViewController: 0x7fc893f09770> while a presentation or dismiss is in progress!
I've tried using:
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute:....
The warning message goes away but the problem is that I have no access to all the variables that I obtained from the second view for use in the third view.
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
if self.answerStatus == "Correct!" {
self.correctWrongStatusLabel.text = self.answerStatus
self.praiseLabel.text = "Good job!"
self.correctAnswerIsLabel.text = ""
let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.fireTimer), userInfo: nil, repeats: false)
self.fireTimer()
} else if self.answerStatus == "Wrong!" {
self.correctWrongStatusLabel.text = self.answerStatus
self.praiseLabel.text = "Maybe next time!"
self.correctAnswerIsLabel.text = "回答 : \(self.correctAnswerIs)"
let timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(self.fireTimer), userInfo: nil, repeats: false)
self.fireTimer()
}
})
#objc func fireTimer() {
delegate?.answerStatusReceived(answerStatusString: answerStatusString)
self.dismiss(animated: true, completion: nil)
}
After the second view appear with the quiz, when the user select an answer, it will checked it against the correct answer and display a response saying the answer is correct or wrong. the response view must automatically closes after displaying for XX seconds.
I think you can't dismiss VC while in load, even if you add delay but no guarantee. Try add timer in viewDidAppear. Also, your self.fireTimer() doesn't necessary.
override func viewDidLoad() {
super.viewDidLoad()
if self.answerStatus == "Correct!" {
self.correctWrongStatusLabel.text = self.answerStatus
self.praiseLabel.text = "Good job!"
self.correctAnswerIsLabel.text = ""
} else if self.answerStatus == "Wrong!" {
self.correctWrongStatusLabel.text = self.answerStatus
self.praiseLabel.text = "Maybe next time!"
self.correctAnswerIsLabel.text = "回答 : \(self.correctAnswerIs)"
}
}
override func viewDidAppear() {
super.viewDidAppear()
if self.answerStatus == "Correct!" {
let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.fireTimer), userInfo: nil, repeats: false)
} else if self.answerStatus == "Wrong!" {
let timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(self.fireTimer), userInfo: nil, repeats: false)
}
}
#objc func fireTimer() {
delegate?.answerStatusReceived(answerStatusString: answerStatusString)
self.dismiss(animated: true, completion: nil)
}
Have you tried removing the DispatchQueue method?
I would do it like this:
override func viewDidLoad() {
super.viewDidLoad()
if self.answerStatus == "Correct!" {
self.correctWrongStatusLabel.text = self.answerStatus
self.praiseLabel.text = "Good job!"
self.correctAnswerIsLabel.text = ""
let timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.fireTimer), userInfo: nil, repeats: false)
self.fireTimer()
} else if self.answerStatus == "Wrong!" {
self.correctWrongStatusLabel.text = self.answerStatus
self.praiseLabel.text = "Maybe next time!"
self.correctAnswerIsLabel.text = "回答 : \(self.correctAnswerIs)"
let timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(self.fireTimer), userInfo: nil, repeats: false)
self.fireTimer()
}
}
#objc func fireTimer() {
delegate?.answerStatusReceived(answerStatusString: answerStatusString)
dismiss(animated: true, completion: nil)
}
I think you included the function FireTimer() inside the viewDidLoad method, so I would add a bracket "}" in the line before the function.
Let me know if it works! :)
simply use:-- dismiss(animated: true, completion: nil) and omit self

ActionSheetPicker Invalid target/action combination used for ActionSheetPicker'

Hi I'm trying to use ActionSheetPicker to let the user select a time for a reminder but I get the error described in the title. Here is my Code:
SelectTime(sender: validCell) // called when tapping a date
// Time Picker
func SelectTime(sender: UIView){
//let timePicker = ActionSheetDatePicker.show(withTitle: "Enter time for reminder", datePickerMode: .time, selectedDate: userDate, target: self, action: , origin: sender.superview!.superview)
let timePicker = ActionSheetDatePicker.show(withTitle: "Enter time for reminder", datePickerMode: .time, selectedDate: userDate, target: self, action: Selector(("timePicked")), origin: sender.superview!.superview, cancelAction: Selector(("timeCanceled")))
timePicker?.minuteInterval = 5
timePicker?.locale = Calendar.current.locale
timePicker?.show()
}
func timePicked(time: Date){
dateSelected.text = formatter.string(for: time)
}
func timeCanceled(){
print("Canceled")
dismiss(animated: true, completion: nil)
}
The cancel code is never called and when I press cancel on the timePicker it shows another time picker underneath it without any buttons.
Gif when canceling
http://www.giphy.com/gifs/l1J3zMQWJ23GpHEaY
The dateSelected is also never called. I'm I doing the selectors wrong?
Change this code
func SelectTime(sender: UIView){
let timePicker = ActionSheetDatePicker.show(withTitle: "Enter time for reminder", datePickerMode: .time, selectedDate: userDate, target: self, action: , origin: sender.superview!.superview)
let timePicker = ActionSheetDatePicker.show(withTitle: "Enter time for reminder", datePickerMode: .time, selectedDate: userDate, target: self, action: Selector(("timePicked")), origin: sender.superview!.superview, cancelAction: Selector(("timeCanceled")))
timePicker?.minuteInterval = 5
timePicker?.locale = Calendar.current.locale
timePicker?.show()
}
func timePicked(time: Date){
dateSelected.text = formatter.string(for: time)
}
func timeCanceled(){
print("Canceled")
dismiss(animated: true, completion: nil)
}
in this code....
let timePicker = ActionSheetDatePicker(title: "Date:", datePickerMode: UIDatePickerMode.date, selectedDate: Date(), doneBlock: {
picker, value, index in
dateSelected.text = formatter.string(for: time)
print("value = \(value)")
print("index = \(index)")
print("picker = \(picker)")
return
}, cancel: { ActionStringCancelBlock in
print("cancel")
return }, origin: sender.superview!.superview)
timePicker?.minuteInterval = 5
timePicker?.locale = Calendar.current.locale

Error in NSTimer (Swift: Xcode)

I am making a timer that will call a function repeatedly with swift 2, Xcode 7. This function sends a local push notification. My timer variable is declared outside the viewDidLoad() in ViewController.swift.
var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self , selector: Selector("notification"), userInfo: nil, repeats: true)
I am getting an error:
Argument Type 'NSObject -> () -> ViewController does not conform to expected type 'AnyObject'
It seems there is some problem with the target self as it is highlighted in red.
Here is my full code if needed:
import UIKit
class ViewController: UIViewController {
var time = 10
var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self , selector: Selector("notification"), 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.
}
#IBAction func btnPressed(sender: AnyObject) {
let alertView = UIAlertController(title: "You won!", message: "Press Go to continue!", preferredStyle: UIAlertControllerStyle.Alert)
self.presentViewController(alertView, animated: true, completion: nil)
alertView.addAction(UIAlertAction(title: "Go", style: UIAlertActionStyle.Default, handler: nil))
}
func notification(){
time--
if (time == 0){
let notification = UILocalNotification()
notification.alertAction = "Go back to App!"
notification.alertBody = "Pls Go back to my App!"
notification.fireDate = NSDate(timeIntervalSinceNow: 0)
UIApplication.sharedApplication().scheduleLocalNotification(notification)
timer.invalidate()
}
}
}
Thanks in advance:)
Try to declare the var timer only setting as NSTimer.init() like:
var timer = NSTimer.init()
And then, put the initialization with scheduledTimerWithInterval inside viewDidLoad():
override func viewDidLoad() {
super.viewDidLoad()
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "notification", userInfo: nil, repeats: true)
}

Does not animate on pressing animate button

Have an animation project which does not animate when I press the button. What am I doing wrong. Here is the code in the view controller:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var startStopAnimating: UIButton!
#IBOutlet weak var imageView: UIImageView!
// image arrays
let frames: [String] = ["frame1.png", "frame2.png", "frame3.png", "frame4.png", "frame5.png", "frame6.png", "frame7.png"]
let swan: [String] = ["swanFrame1", "swanFrame2", "swanFrame3"]
let swirl: [String] = ["swirlFrame1", "swirlFrame2", "swirlFrame3"]
let starryNight: [String] = ["starryNight1", "starryNight2", "starryNight3"]
let doveWithBranch: [String] = ["doveWithBranch1", "doveWithBranch2", "doveWithBranch3"]
let tanCandles: [String] = ["tanCandles1", "tanCandles2", "tanCandles3", "tanCandles4"]
let buddhaFloat: [String] = ["buddhaFloat1", "buddhaFloat2", "buddhaFloat3", "buddhaFloat4", "buddhaFloat5", "buddhaFloat6"]
// timer vars
var timer = NSTimer()
var isAnimating = true
var counter = 1
var arrayIndex = 0
var pauseCheck = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
randomizedFuncs()
}
#IBAction func startStopAnimateButton(sender: AnyObject) {
if isAnimating == true {
timer.invalidate()
startStopAnimating.setTitle("Animate", forState: UIControlState.Normal)
} else {
startStopAnimating.setTitle("Stop Animating", forState: UIControlState.Normal)
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "pauseCheck", userInfo: nil, repeats: true)
}
}
func framesFunc() {
if arrayIndex == swan.count-1 {
arrayIndex = 0
} else {
arrayIndex++
}
imageView.image = UIImage(named: frames[arrayIndex])
counter++
pauseCheck = 1
if counter == 50 {
arrayIndex = 0
timer.invalidate()
isAnimating = false
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "swanFunc", userInfo: nil, repeats: true)
isAnimating = true
counter = 0
arrayIndex = 0
}
}
func swanFunc() {
if arrayIndex == frames.count-1 {
arrayIndex = 0
} else {
arrayIndex++
}
imageView.image = UIImage(named: frames[arrayIndex])
counter++
pauseCheck = 2
if counter == 50 {
arrayIndex = 0
timer.invalidate()
isAnimating = false
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "swirlFunc", userInfo: nil, repeats: true)
isAnimating = true
counter = 0
arrayIndex = 0
}
}
func swirlFunc() {
if arrayIndex == swirl.count-1 {
arrayIndex = 0
} else {
arrayIndex++
}
imageView.image = UIImage(named: frames[arrayIndex])
counter++
pauseCheck = 3
if counter == 50 {
arrayIndex = 0
timer.invalidate()
isAnimating = false
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "starryNightFunc", userInfo: nil, repeats: true)
isAnimating = true
counter = 0
arrayIndex = 0
}
}
func starryNightFunc() {
if arrayIndex == starryNight.count-1 {
arrayIndex = 0
} else {
arrayIndex++
}
imageView.image = UIImage(named: frames[arrayIndex])
counter++
pauseCheck = 4
if counter == 50 {
arrayIndex = 0
timer.invalidate()
isAnimating = false
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "doveWithBranchFunc", userInfo: nil, repeats: true)
isAnimating = true
counter = 0
arrayIndex = 0
}
}
func doveWithBranchFunc() {
if arrayIndex == doveWithBranch.count-1 {
arrayIndex = 0
} else {
arrayIndex++
}
imageView.image = UIImage(named: frames[arrayIndex])
counter++
pauseCheck = 5
if counter == 50 {
arrayIndex = 0
timer.invalidate()
isAnimating = false
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "tanCandlesFunc", userInfo: nil, repeats: true)
isAnimating = true
counter = 0
arrayIndex = 0
}
}
func tanCandlesFunc() {
if arrayIndex == tanCandles.count-1 {
arrayIndex = 0
} else {
arrayIndex++
}
imageView.image = UIImage(named: frames[arrayIndex])
counter++
pauseCheck = 6
if counter == 50 {
arrayIndex = 0
timer.invalidate()
isAnimating = false
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "buddhaFloatFunc", userInfo: nil, repeats: true)
isAnimating = true
counter = 0
arrayIndex = 0
}
}
func buddhaFloatFunc() {
if arrayIndex == buddhaFloat.count-1 {
arrayIndex = 0
} else {
arrayIndex++
}
imageView.image = UIImage(named: frames[arrayIndex])
counter++
pauseCheck = 7
if counter == 50 {
arrayIndex = 0
timer.invalidate()
isAnimating = false
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "frames Func", userInfo: nil, repeats: true)
isAnimating = true
counter = 0
arrayIndex = 0
}
}
// pauses the images and restarts them where they left off, its called in the start/stop action
func pauseCheckFunc() {
if pauseCheck == 1 {
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "framesFunc", userInfo: nil, repeats: true)
} else if pauseCheck == 2 {
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "swanFunc", userInfo: nil, repeats: true)
} else if pauseCheck == 3 {
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "swirlFunc", userInfo: nil, repeats: true)
} else if pauseCheck == 4 {
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "starryNightFunc", userInfo: nil, repeats: true)
} else if pauseCheck == 5 {
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "doveWithBranchFunc", userInfo: nil, repeats: true)
} else if pauseCheck == 6 {
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "tanCandlesFunc", userInfo: nil, repeats: true)
} else if pauseCheck == 7 {
timer.invalidate()
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "buddhaFloatFunc", userInfo: nil, repeats: true)
}
}
func randomizedFuncs() {
let randomNumber = Int(arc4random_uniform(UInt32(7)))
if randomNumber == 0 {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "swanFunc", userInfo: "nil", repeats: true)
} else if randomNumber == 1 {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "framesFunc", userInfo: "nil", repeats: true)
} else if randomNumber == 2 {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "swirlFunc", userInfo: "nil", repeats: true)
} else if randomNumber == 3 {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "starryNightFunc", userInfo: "nil", repeats: true)
} else if randomNumber == 4 {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "doveWithBranchFunc", userInfo: "nil", repeats: true)
} else if randomNumber == 5 {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "tanCandlesFunc", userInfo: "nil", repeats: true)
} else if randomNumber == 6 {
timer = NSTimer.scheduledTimerWithTimeInterval(0.1, target: self, selector: "buddhaFloatFunc", userInfo: "nil", repeats: true)
}
}
}
You're using pauseCheck as a selector but that's not a function in your code. I think you meant pauseCheckFunc?
Also I don't see anywhere in your code a command to actually start animating. You also don't properly set animation frames on your UIImages. It's unclear why you're using timers to animate images. You can just set an array of images to the animationImages property of your UIImages, and just use startAnimating() and stopAnimating() to start and stop animation.

Resources