How to do a CountDown timer using Swift - format

Hello I am developing a countdown timer,which has to stop after 8 hours. Here it is:
import UIKit
class ViewController: UIViewController {
var timer = NSTimer()
var counter = 0
#IBOutlet weak var Label: UILabel!
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 Start(sender: AnyObject) {
counter = 28800
Label.text = String(counter)
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("updateTimer"), userInfo: nil, repeats: true)
}
func updateTimer () {
counter -= 1
Label.text = String(counter)
}
#IBAction func Stop(sender: AnyObject) {
timer.invalidate()
}
}
But in stead of having 28800 seconds (which is 8hours)I want to display 08:00:00 , 07:59:59 , 07:59:58, so on... At the moment it is showing 28800, 28799, 28798, so on. Do you have an idea how to format it as a real clock (08:00:00)?

I had the same problem and pretty much a noob in xcode/swift - but after reviewing several sources, here's what I put together that works for me:
Replace your:
func updateTimer () {
counter -= 1
Label.text = String(counter)
}
With this:
func updateTimer () {
counter -= 1
let hours = Int(counter) / 3600
let minutes = Int(counter) / 60 % 60
let seconds = Int(counter) % 60
Label.text = String(format: "%02i:%02i:%02i",hours,minutes,seconds)
}
(xcode 8.1 warns about use of "let" or "var" for hours/minutes/seconds, but it still works)
Result look like:
00:00:00

Related

Thread 1: EXC_BAD_ACCESS when use selector with two args

It crash inside runTimer() because of two args. If I put only one or nothing - it works normal.
Crash forward to AppDelegate and error is
Thread 1: EXC_BAD_ACCESS (code=1, address=0x4)
var timer = Timer()
var seconds = Int()
#IBOutlet weak var twoMinView: UIView!
#IBOutlet weak var twoMinLabel: UILabel!
#objc func twoMinTimer() {
seconds = 120
runTimer(view: twoMinView, label: twoMinLabel)
}
#objc func runTimer(view: UIView, label: UILabel) {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(MyViewController.updateTimer(view:withLabel:)), userInfo: nil, repeats: true)
}
#objc func updateTimer(view: UIView, withLabel label: UILabel) {
seconds -= 1
if seconds < 1 {
view.isHidden = true
timer.invalidate()
if view == twoMinView {
streamView.isHidden = false
}
}
label.text = timeString(time: TimeInterval(seconds))
}
#objc func timeString(time: TimeInterval) -> String {
let minutes = Int(time) / 60 % 60
let seconds = Int(time) % 60
return String(format: "%02i : %02i", minutes, seconds)
}
Just delete updateTimer and replace runTimer with next one
#objc func runTimer(view: UIView, label: UILabel) {
timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true, block: { (timer) in
if self.seconds < 1 {
view.isHidden = true
timer.invalidate()
if view == self.twoMinView {
self.streamView.isHidden = false
}
}
label.text = self.timeString(time: TimeInterval(self.seconds))
self.seconds -= 1
})
}

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.
}
}

Spin button infinitely: Swift

I found this code that allows you to rotate/spin 90 degrees when button is pushed in Swift. But what I would like to do is rotate/spin the button infinitely when it is pushed, and stop spinning when the button is pushed again. Here is the code I have:
import UIKit
class ViewController: UIViewController {
#IBOutlet var otherbutton: UIButton!
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 Rotate(sender: AnyObject) {
UIView.animateWithDuration(1.0,
animations: ({
self.otherbutton.transform = CGAffineTransformMakeRotation(90)
}))
}
}
You can use a CABasicAnimation to animate it infinitely as follow:
class ViewController: UIViewController {
#IBOutlet weak var spinButton: UIButton!
// create a bool var to know if it is rotating or not
var isRotating = false
#IBAction func spinAction(sender: AnyObject) {
// check if it is not rotating
if !isRotating {
// create a spin animation
let spinAnimation = CABasicAnimation()
// starts from 0
spinAnimation.fromValue = 0
// goes to 360 ( 2 * π )
spinAnimation.toValue = M_PI*2
// define how long it will take to complete a 360
spinAnimation.duration = 1
// make it spin infinitely
spinAnimation.repeatCount = Float.infinity
// do not remove when completed
spinAnimation.removedOnCompletion = false
// specify the fill mode
spinAnimation.fillMode = kCAFillModeForwards
// and the animation acceleration
spinAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
// add the animation to the button layer
spinButton.layer.addAnimation(spinAnimation, forKey: "transform.rotation.z")
} else {
// remove the animation
spinButton.layer.removeAllAnimations()
}
// toggle its state
isRotating = !isRotating
}
}
It should be the same as yours.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var spinButtton: UIButton!
var isRotating = false
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 spinAction(sender: AnyObject) {
if !isRotating {
let spinAnimation = CABasicAnimation()
// start from 0
spinAnimation.fromValue = 0
// goes to 360
spinAnimation.toValue = M_1_PI * 2
// define how long it will take to complete a 360
spinAnimation.duration = 1
// make spin infinitely
spinAnimation.repeatCount = Float.infinity
// do not remove when completed
spinAnimation.removedOnCompletion = false
// specify the fill mode
spinAnimation.fillMode = kCAFillModeForwards
// animation acceleration
spinAnimation.timingFunction = CAMediaTimingFunction (name: kCAMediaTimingFunctionLinear)
// add the animation to the button layer
spinAnimation.layer.addAnimation(spinAnimation, forKey: "transform.rotation.z")
} else {
// remove the animation
spinButtton.layer.removeAllAnimations()
}
// toggle its state
isRotating = !isRotating
}
}

Trying to multiply a variable from a slider to a NSTimer variable.

I made a timer and then I added a slider with a label that presented its value. What I want to do is have my last label (Moneyadded) show a multiplication of the slider value by the current amount of seconds with NStimer.
import UIKit
class ViewController: UIViewController {
var timercount = 0
var timerRunning = false
var timer = NSTimer()
var myVaribale: Int = 0
override func viewDidLoad() {
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
}
func update() {
// fired once a second
myVaribale += 258
}
#IBOutlet weak var timerlabel: UILabel!
func counting(){
timercount += 1
timerlabel.text = "\(timercount)"
var timerValue = timercount.value
}
#IBAction func Clockin(sender: UIButton) {
if timerRunning == false{
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("counting"), userInfo: nil, repeats: true)
timerRunning = true
}
}
#IBAction func Clockout(sender: UIButton) {
if timerRunning == true{
timer.invalidate()
timerRunning = false
}
}
#IBAction func Restart(sender: UIButton) {
timercount = 0
timerlabel.text = "0"
}
#IBOutlet weak var Slider: UISlider!
#IBOutlet weak var Label: UILabel!
#IBAction func valuechanged(sender: UISlider) {
var currentValue = Int(Slider.value)
Label.text = "\(currentValue)"
}
#IBOutlet weak var Moneyadded: UILabel!
\\this is for the label (text) that I want the NStimer to be multiplied by the slider value.
Change your counting function to the following:
/** Gets triggered once every second */
func counting(){
timercount += 1
timerlabel.text = "\(timercount)"
Moneyadded.text = "\(timercount * Int(Slider.value))"
}

XCode 6 - issue with registering a touch

So far I have this app that tracks the number of hits versus misses when the user touches a moving bug on the screen. I am able to register the touches for every time the bug is missed, however not when the bug is touched. Could someone help me understand what I am doing incorrectly and perhaps point me towards a possible solution. Thank you much.
import UIKit
class myViewController2: UIViewController {
#IBOutlet weak var lblBugAmount: UILabel!
var isBuggin = false
var hits = 0
var misses = 0
#IBOutlet weak var lblMissAmount: UILabel!
#IBOutlet weak var lblHitAmount: UILabel!
override func touchesBegan(touches: (NSSet!), withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event);
++misses
--hits
lblMissAmount.text = String(misses)
lblHitAmount.text = String(hits)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func btnStop(sender: UIButton) {
isBuggin = false
super.viewDidLoad()
}
#IBOutlet var bugs : UIImageView!
#IBOutlet weak var numberOfBugsSlider: UISlider!
#IBAction func btnAnimate(sender: UIButton) {
let numberOfBugs = Int(self.numberOfBugsSlider.value) //cast to Int, otherwise slider is decimal
for loopNumber in 0...numberOfBugs+3{
// constants for the animation
let duration = 1.0
let options = UIViewAnimationOptions.CurveLinear | UIViewAnimationOptions.Autoreverse
// randomly assign a delay of 0.3 to 1s
let delay = NSTimeInterval( ((Int(rand()) % 1000)+100.0) / 1000.0)
// constants for the bugs
let size : CGFloat = CGFloat( Int(rand()) % 80 + 100.0) //sizes
let yPosition : CGFloat = CGFloat( Int(rand()) % 200 + 20.0) + 80
// create the bugs
let bugs = UIImageView()
bugs.image = UIImage(named: "bug")
bugs.frame = CGRectMake(0-size, yPosition, size, size)
self.view.addSubview(bugs)
// define the animation
UIView.animateWithDuration(duration, delay: delay, options: options, animations: {
// move the bugs
bugs.frame = CGRectMake(320, yPosition, size, size)
}, completion: { animationFinished in
// remove the bugs
bugs.removeFromSuperview()
})
}
}
#IBAction func bugs(outlet: UIView) {
++hits
--misses
lblHitAmount.text = String(hits)
lblMissAmount.text = String(misses)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
EDIT:
touchesBegan & touchesMoved
override func touchesBegan(touches: (NSSet!), withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event);
var touch : UITouch! = touches.anyObject() as UITouch
location = touch.locationInView(self.view)
self.bugs = touch.locationInView(self.view)
}
override func touchesMoved(touches: (NSSet!), withEvent event: UIEvent) {
super.touchesBegan(touches, withEvent: event);
var touch : UITouch! = touches.anyObject() as UITouch
location = touch.locationInView(self.view)
bugs.center = location
}
User interaction is disabled by default for UIViews and its descendants, you have to explicitly enable it:
// create the bugs
let bugs = UIImageView()
bugs.image = UIImage(named: "bug")
bugs.frame = CGRectMake(0-size, yPosition, size, size)
bugs.userInteractionEnabled = true // <--
self.view.addSubview(bugs)

Resources