i-m trying to learn how to code and working on my first ever app. it is some gym app. and i want to have a timer and a label to be changed after presing a button.
This is my code until now but i cant figure it out how to display the next label and the next timer to countdown after presing the button.
class _daysday1ViewController: UIViewController {
#IBOutlet weak var exerciseNameLabel: UILabel!
#IBOutlet weak var btnStart: UIButton!
#IBOutlet weak var exercisePicture: UIImageView!
#IBOutlet weak var exerciseDescriptionLabel: UILabel!
#IBOutlet weak var timerLabel: UILabel!
#IBAction func nextButtonTapped(sender: AnyObject) {
var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("update"), userInfo: nil, repeats: true)
count = countList[0]
}
var exerciseIndex = 0
var exerciseList = ["12 reps at 80% of capicity" , " 10 reps at 90%" , "7 to 10 reps at full capacity"]
var countList = [4 , 6 ,8]
var count = 1
override func viewDidLoad() {
super.viewDidLoad()
}
func update() {
if(count >= 0) {
timerLabel.text = String(count--)
self.btnStart.enabled = false
return
}
btnStart.enabled = true
exerciseDescriptionLabel.text = exerciseList[0]
}
`
Your timer will go away almost as soon as it's created, because you declared the timer var within the nextButtonTapped function. That function finishes quickly, and your timer goes away when it finishes.
To fix this, declare the timer var at the class level, the same place you declared the count var, like this:
var timer: NSTimer?
Declaring it as an optional (?) allows it be nil until the next button is tapped.
To create it, simply change the line of code in nextButtonTapped to begin with this:
self.timer = ...
Instead of this:
var timer = ...
In your func nextButtonTapped() method, you can include the code for this. The #IBAction will make this method fire every time the button is touched, so if you need variables to change with this action simple outline what you want to change between the {};
example:
var currentExercise = 0
#IBAction func nextButtonTapped() {
btnStart.textLabel.text = "New Text To Display"
currentExercise += 1
exerciseDescriptionLabel.text = exerciseList[currentExercise]
}
Related
I couldn't figure out how to copy value of variable into another variable in Swift, an example code for this in python would be
def assignVariable():
x=1
y=x
return y
RESULT 1
When I did this it doesn't seem to work in Swift. Is there any solution to this or am I doing something wrong?
Edit: problem is at
var originalCount=countDown
it gave me Use of unresolved identifier 'countDown' but when I assign it literally it works. Here's my swift code
import Cocoa
class MainWindow: NSWindowController {
var hitCount = 0
var started:Bool = false
var timer = 10
var colorList: [NSColor] = [ NSColor.black,NSColor.blue,NSColor.brown,NSColor.cyan,NSColor.darkGray,NSColor.gray,NSColor.green,NSColor.lightGray,NSColor.magenta,NSColor.orange,NSColor.purple,NSColor.red,NSColor.white,NSColor.yellow]
#IBOutlet weak var button1: NSButton!
#IBOutlet weak var scrubber1: NSScrubber!
#IBOutlet weak var display: NSTextField!
override func windowDidLoad() {
super.windowDidLoad()
// Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.
}
var countdown=10
var originalCount=countDown
//(countdown,originalCount) = (10,10) //it works if i use this instead
func startGame(){
if(countDown>0 || started==true){
display.stringValue=String(countDown)
countDown-=1
let seconds = 1.0
DispatchQueue.main.asyncAfter(deadline: .now() + seconds) {
self.startGame()
}
}else{
display.stringValue="Done "+String(hitCount)+" Taps in " + String(originalCount) + "Tap to RESET"
started=false
countDown=10;
}
}
#IBAction func labelPress(_ sender: Any) {
display.stringValue="__RESET__"
hitCount=0
countDown=10
started=false
}
#IBAction func buttonPressed(_ sender: Any) {
if started==false{
startGame()
}
button1.bezelColor = colorList[Int.random(in: 0..<colorList.count)]
started=true
button1.title=String(hitCount)
hitCount+=1
}
}
You can't initialise one variable with another at the top level in your class. Looking at your code I don't think that originalCount needs to be a property, move it inside startGame() instead and make it a local variable and also use let since it isn't changing
var countdown=10
func startGame(){
let originalCount = countDown
if(countDown>0 || started==true){
...
}
I am trying to switch the displayed image in an UIImageView to different images based on an timed event by defining the what image should be displayed by I and the app works but when the timer gets to 5 the app crashes. if anyone can help me out then that would be great (also the Ad is the beginning of the image name so AD_1 - AD_4)
import UIKit
class ViewController: UIViewController {
//this is for declaring all the profile buttons
#IBOutlet weak var Icon_1: UIButton!
#IBOutlet weak var Icon_2: UIButton!
#IBOutlet weak var Icon_3: UIButton!
#IBOutlet weak var Icon_4: UIButton!
#IBOutlet weak var Icon_5: UIButton!
#IBOutlet weak var Icon_6: UIButton!
#IBOutlet weak var Icon_7: UIButton!
#IBOutlet weak var Icon_8: UIButton!
//this is used to swich the images
var i = Int(1)
let timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(fire), userInfo: nil, repeats: false)
//this is for the view
#IBOutlet weak var ad_view: UIView!
//this is for when the user swipes left
#IBAction func Icon_Swipe_Left(_ sender: Any) {
Icon_1.isHidden = true
Icon_2.isHidden = true
Icon_3.isHidden = true
Icon_4.isHidden = true
Icon_5.isHidden = false
Icon_6.isHidden = false
Icon_7.isHidden = false
Icon_8.isHidden = false
}
//this is when the user swipes right
#IBAction func Icon_Swipe_Right(_ sender: Any) {
Icon_1.isHidden = false
Icon_2.isHidden = false
Icon_3.isHidden = false
Icon_4.isHidden = false
Icon_5.isHidden = true
Icon_6.isHidden = true
Icon_7.isHidden = true
Icon_8.isHidden = true
}
// this is for decareing the image frame for the adds
#IBOutlet weak var Ad_Frame: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//this is for showing the fist set of icons
Icon_1.isHidden = false
Icon_2.isHidden = false
Icon_3.isHidden = false
Icon_4.isHidden = false
//this is for hideing the second set of icons
Icon_5.isHidden = true
Icon_6.isHidden = true
Icon_7.isHidden = true
Icon_8.isHidden = true
self.Ad_Frame.image = UIImage(named: "AD_\(i)")
}
#objc func fire()
{
i += 1
self.Ad_Frame.image = UIImage(named: "AD_\(i)")
}
}
Two things:
1: you say you have images AD_1 - AD_4 - that's only four images, so it won't cope with the fifth! I'm assuming you mean AD_1 - AD_5
2: More importantly, you start with i = 1, and then add 1 before trying to display the image, so you're actually trying to display images 2...6.
Increment i after displaying the image, not before
Change fire so that it starts over once 5 is reached
#objc func fire() {
self.Ad_Frame.image = UIImage(named: "AD_\(i)")
i += 1
if i > 4 { i = 1 }
}
Off-topic but I would recommend renaming i to something more readable like counter for instance. Single letter variables are not recommended apart from in for loops. Also when declaring it you don't need to call Int(...) but assign the value directly instead, var counter = 1
New to watch development however....
My app gets the user to select a duration for a countdown timer using a slider on one interface controller as shown below:
class game_settings: WKInterfaceController {
#IBOutlet weak var halflength: WKInterfaceSlider!
#IBOutlet weak var halflengthdisplay: WKInterfaceLabel!
#IBOutlet var sethalflengthbutton: WKInterfaceButton!
#IBAction func halfsliderdidchange(value: Float) {
halflengthdisplay.setText("\(value)")
}
override func contextForSegueWithIdentifier(initialhalftogame: String) -> AnyObject? {
// You may want to set the context's identifier in Interface Builder and check it here to make sure you're returning data at the proper times
// Return data to be accessed in ResultsController
return self.halflengthdisplay
}
}
i got this from the following question: Passing data question
then i want the selected interval to be used for the timer on another interface controller as shown below.
class main_game_controller: WKInterfaceController {
#IBOutlet weak var WKTimer: WKInterfaceTimer!//timer that the user will see
var internaltimer : NSTimer?
var ispaused = false
var elapsedTime : NSTimeInterval = 0.0
var StartTime = NSDate()
#IBOutlet var extratime_button: WKInterfaceButton!
#IBOutlet var endgame_button: WKInterfaceButton!
#IBOutlet var sanction_button: WKInterfaceButton!
#IBOutlet var goal_button: WKInterfaceButton!
#IBOutlet var additional_time_timer: WKInterfaceTimer!
#IBOutlet var reset_timer_button: WKInterfaceButton!
#IBOutlet var stop_timer_button: WKInterfaceButton!
#IBOutlet var Start_timer_button: WKInterfaceButton!
override func awakeWithContext(context: AnyObject?) {
super.awakeWithContext(context)
var halflengthinterval : NSTimeInterval// variable was written to, but never read
// Configure interface objects here.
if let halflength: String = context as? String {
halflengthinterval = Double(halflength)!
}
}
override func willActivate() {
super.willActivate()
}
#IBAction func Start_button_pressed() {
internaltimer = NSTimer.scheduledTimerWithTimeInterval(halflengthinterval, target:self, selector: Selector("timerdone"), userInfo: nil, repeats:false) //use of unfesolved identifier"halflengthinterval"
WKTimer.setDate(NSDate(timeIntervalSinceNow: halflengthinterval))
WKTimer.start()//use of unresolved identifier "halflengthinterval"
}
#IBAction func stop_timer_button_pressed() {
if ispaused{
ispaused = false
internaltimer = NSTimer.scheduledTimerWithTimeInterval(halflengthinterval - elapsedTime, target: self, selector: Selector("timerDone"), userInfo: nil, repeats: false)//use of unresolved identifier 'halflengthinterval'
WKTimer.setDate(NSDate(timeIntervalSinceNow: halflengthinterval - elapsedTime))//use of unresolved identifier 'halflengthinterval'
WKTimer.start()
StartTime = NSDate()
stop_timer_button.setTitle("Pause")
}
else{
ispaused = true
//get how much time has passed before they paused it
let paused = NSDate()
elapsedTime += paused.timeIntervalSinceDate(StartTime)
//stop watchkit timer on screen
WKTimer.stop()
//stop internal timer
internaltimer!.invalidate()
//ui modification
stop_timer_button.setTitle("Resume")
}
}
I was following the answer provided in this question: WKInterface implementation
as you can see in the commented lines above, I'm receiving several errors associated with the variable halflengthinterval. I get the feeling that I'm not correctly passing the interval value between the two interface controllers, but for the life of me i have no idea how to do it.
Could someone please help me in showing
how to pass the value for the timer from the first interface
controller to the second interface controller and
how to correctly set the countdown timer for the length of time selected by the slider in the first interface controller.
Thanks very much!
Let's fix first the error regarding to NSInterval, NSInterval is just a typealis for the type Double:
typealias NSTimeInterval = Double
So the problem you're facing is how to convert a String to a Double and the way is using the Double constructor like in this way:
Double(IntValue)
Regarding how to pass data from two WKInterfaceController you're doing in the right way, but you have one mistake to fix. If you want to pass data from one WKInterfaceController to another WKInterfaceController using segues you can use the contextForSegueWithIdentifier, but in your case you are returning a NSInterval type or Double and then you're trying to cast as an String and this fail in this line of code always:
// Configure interface objects here.
if let halflength: String = context as? String {
halflengthinterval = Double(halflength)!
}
You have to change it to this line instead using the guard statement if you like or using optional-binding, it's up to you:
guard
guard let halflength = context as? Double else {
return
}
self.halflengthinterval = Double(halflength)
optional-binding
if let halflength = context as? Double {
self.halflengthinterval = Double(halflength)
}
I hope this help you.
Im creating a simple typing app with timer. The timer should be in a form of a progress bar that decrements every second.
To implement the progressbar, I intended to set the progress to 0.1 lesser to the current progress every 1 second. But there is an "Unrecognized selector for instance " error when i set the progress.
Is there any other way to work around.
import Foundation
import UIKit
class TestView: UIViewController, UITextInputTraits {
#IBOutlet weak var TestLabel: UILabel!
#IBOutlet weak var TypingField: UITextField!
#IBOutlet weak var progressView: UIProgressView!
var time : Float = 0.0
var timer: NSTimer!
var test = 0;
var progress : Float = 1
var myMutableString = NSMutableAttributedString()
var testStringArray = ["abode" , "tutorial" , "completed",
"war", "method", "continue",
"machine", "texting" , "iterate"]
var idx = 0;
var setProg : Float = 1
func textFieldDidChange(textField: UITextField) {
let s = TypingField.text!
if(s.characters.last == " "){
let word = s.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
if(!word.isEmpty){
print(testStringArray[idx])
if(word == testStringArray[idx]){
idx++;
TypingField.text = "";
TestLabel.text = testStringArray[idx];
}else{
TypingField.text = "";
}
}
}
}
func setProgress() {
setProg -= 0.1
progressView.progress = setProg <-- cannot decrement progress bar
}
override func viewDidLoad() {
super.viewDidLoad()
TypingField.autocorrectionType = .No
TypingField.autocapitalizationType = .None
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector:Selector("setProgress"), userInfo: nil, repeats: true)
TestLabel.text = testStringArray[idx];
TypingField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You have coded scheduledTimerWithTimeInterval in a manner like it is done with Objective-C. In Swift it is done differently. Instead of:
selector:Selector("setProgress")
just use:
selector:"setProgress"
Change the function declaration for func setProgress() to:
func setProgress(sender: NSTimer)
And change Selector("setProgress") to "setProgress:"
EDIT:
Apparently the method setProgress already exists, so you'll need to rename the function, e.g. to setProgressBar or something to that effect.
Method 'setProgress' with Objective-C selector 'setProgress:' conflicts with setter for 'progress' with the same Objective-C selector
I think the error was fix when I delete and recreate the progressbar.. it may have been as MikeG suggested about incorrect connection on the outlet. Anyways thanks all for your help..
I am making an app where there is a football field and when you click on the Score Zone 7 points are added to the UILabel that marks score. But I have only been able to display a 7 once and if I click again the seven appears again; I want it to add 7 more to make a 14.
#IBAction func touchdownMD(sender: AnyObject) {
var pointsMD = Int()
scoreMD.text = "\(pointsMD + 7)"
}
#IBOutlet var scoreSH: UILabel!
When you initialize pointsMD inside of the touchdownMD: function, it starts from 0 whenever the function is called.
In order to fix this, you need to declare it at the class level. For example:
var pointsMD = Int() //initialize pointsMD at the class level
#IBAction func touchdownMD(sender: AnyObject){
pointsMD+=7 //add 7 to pointsMD
scoreMD.text = "\(pointsMD)"
}
That way, pointsMD will not reset whenever touchdownMD: is called, it will instead just increment as needed.
So, here's what your code could look like:
var pointsMD = Int()
#IBAction func touchdownMD(sender: AnyObject) {
pointsMD+=7
scoreMD.text = "\(pointsMD)"
}
#IBOutlet var scoreSH: UILabel!