switching image on timed event in swift - swift

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

Related

Secure text .echosbullets not working for password field

Here's what I've got:
#IBOutlet weak var password: NSSecureTextField!
#IBOutlet weak var shwpswd: NSButton! //Checkbox
#IBOutlet weak var pswdcell: NSSecureTextFieldCell! //Cell
#IBAction func shwpswd(_ sender: Any) {
if(shwpswd.state == 1) {
pswdcell.echosBullets = false // Turn the Secure text into regular text
}
else if(shwpswd.state == 0) {
pswdcell.echosBullets = true // Secure text
}
}
Everything seems to run fine, except the text in the password field doesn't change states between echoing bullets and echoing the real text. Everything is linked together properly too - Cell is within the text field, password button is in the view and the outlet works. I'm wondering if this is another one of the "Swift on mac < Swift on iOS cases".
EDIT: Here is the final solution, should anyone care to see it:
#IBOutlet weak var shwpswd: NSButton! //Checkbox
#IBOutlet weak var visPswd: NSTextfield! //hidden regular box to show chars
#IBOutlet weak var password: NSSecureTextField! //visible initial secure box
#IBAction func shwpswd(_ sender: Any) {
if(shwpswd.state == 1) {
self.visPswd.stringValue = self.password.stringValue //Sync both the text fields
self.password.isHidden = true //hide the secure field
self.visPswd.isHidden = false //show the real character echo field
}
else if(shwpswd.state == 0) {
self.password.stringValue = self.visPswd.stringValue //Sync the two
self.password.isHidden = false // Inverse of above
self.visPswd.isHidden = true
}
}
Note the text fields password and visPswd are the same size and position in the view - one remains hidden at all times to avoid overlapping. When the user enters values in either the password or visPswd field, it syncs with the other field when the checkbox state is changed.
You can accomplish what you want adding a second text field in top of your secure field. Add an IBAction to your check box to switch your fields isHidden property and copy the other textField stringValue and make it the first responder. Your implementation should look like something like this:
import Cocoa
class ViewController: NSViewController {
#IBOutlet weak var password: NSSecureTextField!
#IBOutlet weak var showPassword: NSTextField!
#IBOutlet weak var shwpswd: NSButton!
override func viewDidLoad() {
super.viewDidLoad()
shwpswd.state = .off
showPassword.isHidden = true
}
override func viewDidAppear() {
super.viewDidAppear()
password.window?.makeFirstResponder(password)
}
#IBAction func showHidePassword(_ sender: NSButton) {
showPassword.isHidden.toggle()
password.isHidden.toggle()
if !showPassword.isHidden {
showPassword.stringValue = password.stringValue
showPassword.becomeFirstResponder()
} else {
password.stringValue = showPassword.stringValue
password.becomeFirstResponder()
}
}
}
show/hide password sample

Need button to change labels when clicked

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

Displaying an Array of type Double on UILabel in Xcode

I am trying to make a basic shopping cart app where you can add an item to your cart, store the cost of the item in an array and then have the array displayed when you click "Receipt". However, every time I click "Receipt" on my app, the simulator crashes and displays
"Thread1: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, subcode=0x0)
beside my line of code that reads "allItems += item". If anyone has any ideas as to how I can my array of numbers displayed in a UILabel using a for in loop, please let me know. I will post source code below. Thanks in advance
class ViewController: UIViewController {
var priceOfApple = 1.75
var cart = [Double]()
var total = 0.00
#IBOutlet weak var appName: UILabel!
#IBOutlet weak var Balance: UILabel!
#IBOutlet weak var Instructions: UILabel!
#IBOutlet weak var redApple: UIButton!
#IBOutlet weak var appleInfo: UILabel!
#IBOutlet weak var addToCart: UIButton!
#IBOutlet weak var itemsPurchased: UILabel!
#IBAction func selectedApple(sender: AnyObject) {
Instructions.hidden = true
appleInfo.hidden = false
addToCart.hidden = false
}
#IBAction func purchaseApple(sender: AnyObject) {
cart.append(priceOfApple)
total += priceOfApple
Balance.text = "Balance : \(total)"
Instructions.hidden = false
appleInfo.hidden = true
addToCart.hidden = true
}
#IBAction func viewReceipt(sender: AnyObject) {
redApple.hidden = true
Instructions.hidden = true
itemsPurchased.hidden = false
for item in cart {
var allItems = Double(itemsPurchased.text!)!
allItems += item
allItems = Double(itemsPurchased.text!)!
}
}
}
If I understand correctly, this is what you should do:
First, create a variable outside the for-loop,
then inside the loop that variable will start storing every value in the array separated by " ". Once It is done, you can display its value in the Label.
var itemsInCart = ""
for items in cart{
itemsInCart += String(items) + " "
}
itemsPurchased.text = itemsInCart
I hope it helps!!!
A cleaner and safer way to do it:
let result = cart.flatMap { Double(itemsPurchased.text ?? String()) }.reduce(0: combine: +)
Doing that, you shouldn't get EXC_BAD_INSTRUCTION anymore, but you should still check if is the text convertible to a Double.

Disable button in cocoa application OS X

I would like to have the submit button enabled once some fields on a form have been validated. Currently the preview function works great, preview button provides the validation I need. Working on Xcode 7 and swift 2. I would really appreciated if someone can point me in the right direction. Below is the code I currently have:
import Cocoa
#NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
var projectFlag = false
var descriptionFlag = false
var releaseFlag = false
// Fields
#IBOutlet weak var projectNumberTextField:NSTextField!
#IBOutlet weak var projectDescriptionTextField:NSTextField!
#IBOutlet weak var releaseFolderNameTextField:NSTextField!
#IBOutlet weak var passwordTextField:NSTextField!
// Labels for preview
#IBOutlet weak var label1: NSTextField!
#IBOutlet weak var label2: NSTextField!
#IBOutlet weak var label3: NSTextField!
#IBOutlet weak var label4: NSTextField!
#IBOutlet weak var label5: NSTextField!
// Quit Button :: Quits the application
#IBAction func quitButton(sender: AnyObject) {
NSApplication.sharedApplication().terminate(self)
}
// Preview button behavior
#IBAction func previewButton(sender: AnyObject) {
// Project Number ::
let project = projectNumberTextField.stringValue
label1.stringValue = "\(project)"
if (label1.stringValue == "00-0000") {
label1.stringValue = "Project Number is not valid"
label1.textColor = NSColor.redColor()
projectFlag = false
} else {
label1.textColor = NSColor.blackColor()
projectFlag = true
}
// Project Description :: Name, 2016
let description = projectDescriptionTextField.stringValue
label2.stringValue = "\(description)"
if (label2.stringValue == "Name, 2016") {
label2.stringValue = "Enter a valid project description"
label2.textColor = NSColor.redColor()
descriptionFlag = false
} else {
label2.textColor = NSColor.blackColor()
descriptionFlag = true
}
// Folder Release Name :: RELEASE_NAME
let release = releaseFolderNameTextField.stringValue
label3.stringValue = "\(release)"
if (label3.stringValue == "RELEASE_NAME") {
label3.stringValue = "Enter a valid folder release name"
label3.textColor = NSColor.redColor()
releaseFlag = false
} else {
label3.textColor = NSColor.blackColor()
releaseFlag = true
}
// Password :: If needed
let password = passwordTextField.stringValue
label4.stringValue = "\(password)"
// Preview :: Code format for txt file
let preview = "\(project)|"+"\(description)|"+"\(release)|"+"\(password)/"
label5.stringValue = "\(preview)"
}
// Submit button behavior
#IBAction func submitButton(Sender: AnyObject) {
}
func applicationDidFinishLaunching(aNotification: NSNotification) {
// Insert code here to initialize your application
}
func applicationWillTerminate(aNotification: NSNotification) {
// Insert code here to tear down your application
}
}

if statement returning a value not working for UiLabel

my fairly new to swift and programming, I'm trying to display a value from an if statement. Here is my func within my UiLabel. I've tried a few variations along the same lines but it only every returns "calculate.fuelTank" it never seems to trigger the second part to my IF statement?
#IBOutlet weak var startingFuelDisplay: UILabel! //not working yet
func refreshUiopeningFuel() {
if calculate.totalFuel <= Double(calculate.fuelTank) {
print (Double(calculate.fuelTank)) // FuelTank
} else {
print (calculate.totalFuel) // TotalFuel
}
Do I need to add a bool argument to trigger "else"? I have also tried using the "return" function with initialised string which included the value I was trying to extract, finally I need this to work for another display.
here is my full view controller code (i'm new I'm sure it could be cleaner)
import UIKit
class ViewController: UIViewController {
let calculate = Inputs ( raceLaps: 13, fuelRate: 3.7, fuelTank: 110, laptime: 85.456, tyreWear: 0.05 )
#IBOutlet weak var rate: UITextField!
#IBOutlet weak var laps: UITextField!
#IBOutlet weak var tank: UITextField!
#IBOutlet weak var tyreWear: UITextField!
#IBOutlet weak var laptime: UITextField!
#IBOutlet var cancelKeyboard: UITapGestureRecognizer!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//Looks for single or multiple taps.
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
view.addGestureRecognizer(tap)
}
//Calls this function when the tap is recognized.
func dismissKeyboard() {
//Causes the view (or one of its embedded text fields) to resign the first responder status.
view.endEditing(true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
refreshUiFuel()
refreshUiStops()
refreshUiTyreLife()
refreshUiTyreLifeLaps()
refreshUiopeningFuel()
refreshUiBoxOnLap ()
}
#IBAction func calculate(sender: UIButton) {
if let rateVal = Double(rate.text!),
tankVal = Int(tank.text!),
lapVal = Int(laps.text!),
wearVal = Double(tyreWear.text!),
laptimeVal: Float = 85.456 {
let fuelModel = Inputs(raceLaps: lapVal, fuelRate: rateVal, fuelTank: tankVal, laptime: laptimeVal, tyreWear: wearVal )
totalFuelDisplay.text = ("\(Double(fuelModel.totalFuel))")
totalStopsDisplay.text = ("\(Int(fuelModel.totalStops))")
tyreLifeDisplay.text = ("\(Int(fuelModel.tyreChangesRaceDistanceTotal))")
tyreLifeLapsDisplay.text = ("\(Int(fuelModel.tyreLife))")
startingFuelDisplay.text = ("\(refreshUiopeningFuel())")
}
else {
totalFuelDisplay.text = "missing value"
totalStopsDisplay.text = "missing value"
tyreLifeDisplay.text = "missing value"
tyreLifeLapsDisplay.text = "missing value"
startingFuelDisplay.text = "missing Value"
}
}
#IBOutlet weak var totalFuelDisplay: UILabel!
func refreshUiFuel()->String {
return totalFuelDisplay.text!
}
#IBOutlet weak var totalStopsDisplay: UILabel!
func refreshUiStops()->String {
return totalStopsDisplay.text!
}
#IBOutlet weak var tyreLifeDisplay: UILabel!
func refreshUiTyreLife()->String {
return tyreLifeDisplay.text!
}
#IBOutlet weak var tyreLifeLapsDisplay: UILabel!
func refreshUiTyreLifeLaps()->String {
return tyreLifeLapsDisplay.text!
}
#IBOutlet weak var pitOnLapDisplay: UILabel!
func refreshUiBoxOnLap () {
}
#IBOutlet weak var startingFuelDisplay: UILabel! //not working yet
func refreshUiopeningFuel() ->Double {
print(calculate.fuelTank)
print(calculate.totalFuel)
if calculate.totalFuel <= Double(calculate.fuelTank) {
return Double(calculate.fuelTank) // FuelTank
} else {
return calculate.totalFuel // TotalFuel
}
}
}
all helped welcomed
Judging from the natural real-world logic, it appears you've simply reversed the if/else logic. It would seem that if totalFuel is less than the tank's capacity (the if clause), you should return totalFuel in that case, and return the tank capacity in the else clause.