How to go through array with button press - ios

I have an array that contains different information,
how can I iterate through the array with a button press? I have two buttons, and I need to allow one to move forward in the array and the back button to display the previous index.
#IBOutlet weak var backButton: UIButton!
#IBOutlet weak var nextButton: UIButton!
#IBOutlet weak var infoLabel: UILabel!
#IBOutlet weak var pageControl: UIPageControl!
Let infoArray = ["info1","info2","info3","info4"]
#IBAction func nextTapped(_ sender: Any) {
// Change the label based on the selected index in array
}
#IBAction func backTapped(_ sender: Any) {
//Return to previous index and update label text
}
I also added page control for better UX, but for now I'm just worried about learning how to even change the label through button Tap.
My guess would be to start the index at 0 which would be info1 and go from there. I can worry about saving index state later.
Any help is much appreciated.

The logic should look something like this
let infoArray = ["info1","info2","info3","info4"]
func viewDidLoad() {
pageControl.numberOfPages = infoArray.count
pageControl.currentPage = 0
}
#IBAction func nextTapped(_ sender: Any) {
// Change the label based on the selected index in array
guard pageControl.currentPage + 1 < infoArray.count else {
return
}
pageControl.currentPage += 1
}
#IBAction func backTapped(_ sender: Any) {
//Return to previous index and update label text
guard pageControl.currentPage - 1 >= 0 else {
return
}
pageControl.currentPage -= 1
}
When a user taps a page control to move to the next or previous page, the control sends the valueChanged event for handling by the delegate. The delegate can then evaluate the currentPage property to determine the page to display. The page control advances only one page in either direction.

Please check the below code you can do something like this to move your array forward and backward. Please add other checks according to your need.
var i = 0
let infoArray = ["info1","info2","info3","info4"]
#IBAction func nextTapped(_ sender: Any) {
// Change the label based on the selected index in array
if i >= 0 && i < infoArray.count{
dataLbl.text = infoArray[i]
}
if i > 3 {
i = i-1
} else {
i = i+1
}
}
#IBAction func backTapped(_ sender: Any) {
//Return to previous index and update label text
if i >= 0 && i < infoArray.count-1 {
dataLbl.text = infoArray[i]
}
if i < 0 {
i = i+1
} else {
i = i-1
}
}

Related

My Question is about changing a UIImage when a button is pressed

So I am quite new to coding, learning Swift 3 on Udemy. I'm trying to test my skills by building a music app that contains 3 sound files, at the moment I am struggling to get the image of the current song that should be playing once my UIButton is pressed. I have created an array containing the image files but for some reason it only shows 2 out of the 3 images and will not go further nor will it let me loop the images, any and all suggestions are welcome.
I have tried a for-in loop which is not what I want at the moment. I am trying to get the function to update songImage to accept my array and link to the sender.tag property to cycle through the images
class ViewController: UIViewController {
// Instance Variables
var playTheSong : AVAudioPlayer!
var imageArray = ["songImage1", "songImage2", "songImage3"]
var allSongNamesAndDescriptions = MusicClassBank()
var nextImage = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
albumArtwork.image = UIImage(named: "songImage3")
}
#IBAction func buttonPressed(_ sender: UIButton) {
updateSongImage(selectedImageFile: imageArray[sender.tag - 1])
nextImage = nextImage + 1
}
#IBOutlet weak var albumArtwork: UIImageView!
#IBOutlet weak var nameOfSong: UILabel!
#IBOutlet weak var songDescription: UILabel!
// Cycle through images upon button being pressed.
func updateSongImage(selectedImageFile : String) {
if nextImage <= 3 {
albumArtwork.image = UIImage(named: selectedImageFile)
}
else {
nextImage = 0
}
}
Right now the code is showing just the image displayed upon view load and the next image in the array. I cannot get it to go through the entire array and keep going when the button is pressed.
You are using the "next" UIButton sender.tag as a parameter to change the image, but that tag never changes. So:
In your viewDidLoad() method, you show the third image
When you press the "next" button, you update the image to 1 (probably the sender.tag is 1)
Pressing the button again don't update the image
You can try something like this:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
//Set the first image
updateSongImage(selectedImageFile : imageArray[0])
}
#IBAction func buttonPressed(_ sender: UIButton) {
//If nextImage is less than imageArray.count - 1 (because arrays start with 0), add one to nextImage. Else, nextImage return to zero
nextImage = nextImage < imageArray.count - 1 ? nextImage + 1 : 0
updateSongImage(selectedImageFile: imageArray[nextImage])
}
func updateSongImage(selectedImageFile : String) {
//Here we only need to update the image, because the if is outside
albumArtwork.image = UIImage(named: selectedImageFile)
}

Hiding UIButton if variable has certain value?

I want to hide a UIButton as long as a certain variable has not reached a certain value.
I tried some setHidden and isHidden setups, but I guess I did it all wrong. I don't exactly know where to put these commands.
I have looked for a solution at almost every webpage but I got no idea what everybody is talking about.
import UIKit
class ViewController: UIViewController {
let startvalue = 1000000
#IBOutlet weak var Counter: UITextField!
#IBAction func Button(_ sender: UIButton) {
if number > 1{
number -= 1
Counter.text = String(number)
} else {
Counter.text = "Hurray"
}
}
#IBOutlet weak var Reset: UIButton!
#IBAction func Reset(_ sender: UIButton) {
if number == 1{
number = startvalue
Counter.text = String (number)
}
}
override func viewDidLoad() {
var number = startvalue {
didSet {
if number < 1 {
Reset.isHidden = false
}
}
}
super.viewDidLoad()
}
}
I don't now what I need to put where to hide Result as long as number is greater than 1.
Handle it in the didSet of the variable.
var number = startValue {
didSet {
if number < 1 {
yourButton.isHidden = false
}
}
}
Now, whenever your number is changed, the didSet block will check if the value is less than 1. If so, it'll unhide the button.
Note: Make sure the button is hidden before the view shows. Also, make sure to hide the button if needed on resetting.
Use lowerCamelCase for variable names like they say in the API design guidelines.

Reset Score Button iOS

I want displayBatsmenOneScoreLabel to reset to 0 when the resetScoreButton is hit.
What would be my code for the resetScoreButton?
Here's my code.
var batsmenOneScoreInt: Int = 0
#IBOutlet weak var displayBatsmenOneScoreLabel: UILabel!
#IBAction func BatsmenOneScoreStepper(_ sender: UIStepper) {
let batsmenOneScoreValue = Int(sender.value)
displayBatsmenOneScoreLabel.text = String(batsmenOneScoreValue)
}
#IBAction func resetScoreButton(_ sender: Any) {
//what should I write here...
}
You need to reset the batsman score, it should work.
You can try this code:
#IBAction func resetScoreButton(_ sender: Any) {
let batsmenOneScoreValue = 0
displayBatsmenOneScoreLabel.text = String(batsmenOneScoreValue)
}
For good practice you should first reset the main variable that is holding the score, and then set that variable to the label.
#IBAction func resetScoreButton(_ sender: Any) {
batsmenOneScoreInt = 0;
displayBatsmenOneScoreLabel.text = "\(batsmenOneScoreInt)"
}
#IBOutlet weak var batsmenScoreStepper:UIStepper!
#IBAction func resetScoreButton(_ sender: Any) {
batsmenScoreStepper.value = 0.0;
displayBatsmenOneScoreLabel.text = "\(batsmenScoreStepper.value)"
}
you should first take outlet of your UIStepper and reset it.
You can reset score in button's action(touchup inside) like below...
#IBAction func resetScoreButton(_ sender: Any) {
displayBatsmenOneScoreLabel.text = "0"
//do something here...
}
EDIT:
In case if you want to reset score variable you need to set batsmenOneScoreInt = 0 in resetScoreButton method.

My variable value is different than the value the prepareForSegue takes when transferring?

Essentially, my variable (playerErrors) is updated by a button push and then the view controller is segued to the next with data transferring. However, the variable's value (which should go up by 1 from 0 for example) transfers as 0 (as if the button wasn't pushed). I have 16 variables in my code that I'm trying to transfer, but oddly half (8) of them DO work and the ones that work are all for the opponent's values. The 8 that don't work are player values (like playerErrors).
I'm new to XCode. I'm taking a class in High School where we're learning to code for the first time, so I'm not very good at it yet, but I've had this issue for days and I cannot solve it! I've included my view controller's code below.
When youErrorDeep is triggered, it prints "segueing from self 0 to dvc: 0".
//
// ThirdViewController.swift
// rally
//
// Created by GBernero on 12/6/16.
// Copyright © 2016 GBernero. All rights reserved.
//
import UIKit
class ThirdViewController: UIViewController {
#IBOutlet weak var emptyTennisCourt: UIImageView!
#IBOutlet weak var labelOpponent: UILabel!
#IBOutlet weak var labelPlayer: UILabel!
var playerWinners = 0 //holds total amount of winners player has hit
var playerShortWinners = 0 //holds amount of winners play has hit short
var playerDeepWinners = 0 //holds amount of winners play has hit deep
var playerErrors = 0 //holds total amount of errors play has hit
var playerErrorsLeft = 0 //holds amount of errors play has hit left
var playerErrorsRight = 0 //holds amount of errors play has hit right
var playerErrorsDeep = 0 //holds amount of errors play has hit deep
var playerErrorsNet = 0 //holds amount of errors play has hit in the net
var opponentWinners = 0 //holds total amount of winners opponent has hit
var opponentShortWinners = 0 //holds amount of winners opponent has hit short
var opponentDeepWinners = 0 //holds amount of winners opponent has hit deep
var opponentErrors = 0 //holds total amount of errors opponent has hit
var opponentErrorsLeft = 0 //holds amount of errors opponent has hit left
var opponentErrorsRight = 0 //holds amount of errors opponent has hit right
var opponentErrorsDeep = 0 //holds amount of errors opponent has hit deep
var opponentErrorsNet = 0 //holds amount of errors opponent has hit in the net
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
let dvc = segue.destination as! SixthViewController
dvc.playerErrorsDeep = self.playerErrorsDeep
print("segueing from self \(self.playerErrorsDeep) to dvc: \(dvc.playerErrorsDeep)")
dvc.playerErrorsNet = self.playerErrorsNet
dvc.playerErrorsLeft = self.playerErrorsLeft
dvc.playerErrorsRight = self.playerErrorsRight
dvc.playerErrors = self.playerErrors
dvc.playerShortWinners = self.playerShortWinners
dvc.playerDeepWinners = self.playerDeepWinners
dvc.playerWinners = self.playerWinners
dvc.opponentErrorsDeep = self.opponentErrorsDeep
print("segueing to dvc2: \(dvc.opponentErrorsDeep)")
dvc.opponentErrorsNet = self.opponentErrorsNet
dvc.opponentErrorsLeft = self.opponentErrorsLeft
dvc.opponentErrorsRight = self.opponentErrorsRight
dvc.opponentErrors = self.opponentErrors
dvc.opponentShortWinners = self.opponentShortWinners
dvc.opponentDeepWinners = self.opponentDeepWinners
dvc.opponentWinners = self.opponentWinners
}
override func viewDidLoad()
{
self.navigationItem.setHidesBackButton(true, animated: false) //removes back button from access by user
self.view.backgroundColor = UIColor(patternImage: UIImage(named: "tennis_background.jpg")!) //sets background of view controller to the background image
super.viewDidLoad()
}
#IBAction func youErrorDeep(_ sender: Any)
{
playerErrors += 1
playerErrorsDeep += 1
print("deep \(playerErrors), \(playerErrorsDeep)")
}
#IBAction func youErrorLeft(_ sender: Any)
{
playerErrors += 1
playerErrorsLeft += 1
}
#IBAction func youErrorRight(_ sender: Any)
{
playerErrors += 1
playerErrorsRight += 1
}
#IBAction func youWinnerDeep(_ sender: Any)
{
playerWinners += 1
playerDeepWinners += 1
}
#IBAction func youWinnerShort(_ sender: Any)
{
playerWinners += 1
playerShortWinners += 1
}
#IBAction func youErrorNet(_ sender: Any)
{
playerErrors += 1
playerErrorsNet += 1
}
#IBAction func opponentErrorDeep(_ sender: Any)
{
opponentErrors += 1
opponentErrorsDeep += 1
print( "it happens")
}
#IBAction func opponentErrorLeft(_ sender: Any)
{
opponentErrors += 1
opponentErrorsLeft += 1
}
#IBAction func opponentErrorRight(_ sender: Any)
{
opponentErrors += 1
opponentErrorsRight += 1
}
#IBAction func opponentWinnerDeep(_ sender: Any)
{
opponentWinners += 1
opponentDeepWinners += 1
}
#IBAction func opponentWinnerShort(_ sender: Any)
{
opponentWinners += 1
opponentShortWinners += 1
}
#IBAction func opponentErrorNet(_ sender: Any)
{
opponentErrors += 1
opponentErrorsNet += 1
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destinationViewController.
// Pass the selected object to the new view controller.
}
*/
}
It should work with something like this:
#IBAction func youErrorDeep(_ sender: Any){
playerErrors += 1
playerErrorsDeep += 1
print("deep \(playerErrors), \(playerErrorsDeep)")
self.performSegue(withIdentifier: "segueForYouErrorDeep", sender: self) //instead of "segueForYourErrorDeep" use the identifier for the correct segue
}
You would have to give each segue a unique identifier, but this way you can still use the storyboard to a certain extent.
This also ensures that the segue is executed after the operations.
If you're unsure how to give a segue an identifier, all you have to do is click on the segue graphic and under attributes set the identifier to an arbitrary string.
You aren't calling peformSegueWithIdentifier:sender anywhere in your code, so I assume that you are triggering the segue directly from the action outlet in Interface Builder.
This won't work where you need to execute some code on the button press, since the segue may occur before the #IBAction method executes.
You should remove the segue from the action outlet, create a segue from your View Controller object in Interface Builder, give this segue an identifier and the you can initiate it from your #IBAction method using performSegueWithIdentifier:sender.
Also, for readability and maintainability, I strongly suggest you create a class to store the player state and then you can just pass an instances of this class rather than 16 separate variables

Xcode - Label won't clear when button is pressed

So I'm trying to create a simple function in my app in which a button adds 1 integer to the label when it's pressed and the other one clears it.
Here is the code:
class ViewController: UIViewController {
var number = 0
#IBOutlet weak var tapCount: UILabel!
#IBAction func plusTapped(sender: AnyObject) {
number = number + 1
tapCount.text = String(number)
}
#IBAction func minusTapped(sender: AnyObject) {
var totalNumber = number - number
tapCount.text = String(totalNumber)
}
However the label does clear when the minus button is tapped but when the plus button is tapped after, it adds up from the previous number before the minus button was pressed.
How do I fix this in a way so that it actually clears the label?
#IBAction func minusTapped(sender: AnyObject) {
number = 0 // add this line to reset the counter, the real number
tapCount.text = String(number)
}
Try
#IBAction func minusTapped(sender: AnyObject) {
number = 0
tapCount.text = String(0)
}
I think it's because when you're handling tap on minus you are altering local variable and not changing number itself. You should change "number" too. Se my comments in your's code
class ViewController: UIViewController {
var number = 0
#IBOutlet weak var tapCount: UILabel!
#IBAction func plusTapped(sender: AnyObject) {
number = number + 1
tapCount.text = String(number)
}
#IBAction func minusTapped(sender: AnyObject) {
//here totalNumber is changed but number is still the same
var totalNumber = number - number
tapCount.text = String(totalNumber)
}

Resources