Swift UI - Button back on image gallery - ios

How do I make a back button? I get it wrong the way I want to do it. Thank you in advance.
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var imageView: UIImageView!
let images: [UIImage] = [#imageLiteral(resourceName: "tub"),#imageLiteral(resourceName: "ball"),#imageLiteral(resourceName: "apple"),#imageLiteral(resourceName: "igloo"),#imageLiteral(resourceName: "frog")]
var i : Int = 0
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
#IBAction func nextButton(_ sender: UIButton) {
i = (i+1)%images.count
imageView.image = images[i]
}
#IBAction func backButton(_ sender: UIButton) {
i = (i-1)%images.count
imageView.image = images[i]
}
the back button gives an error

You have 5 images in your array.
When you tap your Back button, suppose i is currently equal to 0:
(i-1) == -1
-1 % 5 == -1
imageView.image = images[-1] // is invalid... there is no array index of -1
If you want the Back button to "wrap around" from 0 (the first image) to 4 (the last image), you should do:
i -= 1
if i < 0 {
i = images.count - 1
}
imageView.image = images[i]
If you want to stop at the first image:
i = max(i - 1, 0)
imageView.image = images[i]

Related

UIImageView slides using Buttons

I have a homework with which I'm stuck. Here it is:
Make a gallery project: a large UIImageView and two buttons below it: Back and Next. Add 10 pictures to the project, and by clicking on the buttons, the previous or next picture should be displayed, respectively.
So I made an array, and some *silly attempt* to go through this array. But i'm 100% sure that there is some simple answer to that.
Thank you!
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var imagesIV: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
}
let images = [UIImage(named: "1"), UIImage(named: "2"), UIImage(named: "3"),UIImage(named: "4"),UIImage(named: "5"),UIImage(named: "6"),UIImage(named: "7"),UIImage(named: "8"),UIImage(named: "9"),UIImage(named: "10")]
var numberOfImages = images.count
var currentImage = 0
#IBAction func forwardButton(_ sender: Any) {
guard case currentImage + 1 < images.count else {return}
currentImage += 1
}
#IBAction func backButton(_ sender: Any) {
}
}
A better way in my opinion is below, specifically to make your code scalable (e.g. if you have 1000 photos, you don't want to add them manually one by one in the array):
class ViewController: UIViewController {
#IBOutlet weak var imagesIV: UIImageView!
var currentImageIndex = 0
var images : [UIImage] = []
override func viewDidLoad() {
super.viewDidLoad()
for a in 1...10 {
if let newImage = UIImage(named: "\(a)") {
images.append(newImage)
}
}
updateImageInImageView()
}
#IBAction func forwardButton(_ sender: Any) {
if currentImageIndex + 1 != images.count { currentImageIndex += 1} else { currentImageIndex = 0}
updateImageInImageView()
}
#IBAction func backButton(_ sender: Any) {
if currentImageIndex != 0 { currentImageIndex -= 1} else { currentImageIndex = images.count - 1}
updateImageInImageView()
}
func updateImageInImageView() {
imagesIV.image = images[currentImageIndex]
}
}
You can try
#IBAction func forwardButton(_ sender: Any) {
guard currentImage + 1 < images.count else {return}
currentImage += 1
imagesIV.image = images[currentImage]
}
#IBAction func backButton(_ sender: Any) {
guard currentImage - 1 >= 0 else {return}
currentImage -= 1
imagesIV.image = images[currentImage]
}

How to go through array with button press

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

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

Cannot assign to value: 'image' is a method [duplicate]

This question already has answers here:
Setting an image for a UIButton in code
(12 answers)
Closed 3 years ago.
I want to change the image displayed by picking a random value from an array of images.
import UIKit
class ViewController: UIViewController {
let imageArray = ["ball1", "ball2", "ball3", "ball4", "ball5"]
var number: Int = 0
#IBOutlet weak var myImage: UIButton!
#IBAction func buttonPressed(_ sender: UIButton) {
number = Int.random(in: 0 ... 4)
myImage.image = UIImage(named: imageArray[number+1])
}
override func viewDidLoad() {
super.viewDidLoad()
myImage.image = UIImage(named: "ball1")
number = Int.random(in: 0 ... 4)
myImage.image = UIImage(named: imageArray[number+1])
}
}
In lines 19, 24, and 26 (whenever I try to change the image) I get the error "Cannot assign to value: 'image is a method". Why is this?
Set image with state property equals to .normal:
import UIKit
class ViewController: UIViewController {
let imageArray = ["ball1", "ball2", "ball3", "ball4", "ball5"]
var number: Int = 0
#IBOutlet weak var myImage: UIButton!
#IBAction func buttonPressed(_ sender: UIButton) {
number = Int.random(in: 0 ... 4)
myImage.setImage(UIImage(named: imageArray[number+1]), for: .normal)
}
override func viewDidLoad() {
super.viewDidLoad()
myImage.setImage(UIImage(named: "ball1"), for: .normal)
number = Int.random(in: 0 ... 4)
myImage.setImage(UIImage(named: imageArray[number+1]), for: .normal)
}
}

Could not cast value of type 'UIView' (0x10d54a4c0) to 'UIButton' (0x10d552120)

there was a question like this already made but I tried the suggestions and it didn't work for me still. :/
I am trying to make a quiz app using this tutorial: https://www.youtube.com/watch?v=KNAQ3Y8PGkM&t=1s
Here is a link to download my project: https://www.dropbox.com/s/bwvg6fyrrzudued/kat%20quiz.zip?dl=0
Everything is perfect except I get the error:
Could not cast value of type 'UIView' (0x10d54a4c0) to 'UIButton' (0x10d552120)
I'd really appreciate some help. I tried everything in my knowledge and searching, thank you. :)
import UIKit
class ViewController: UIViewController {
let questions = ["What color is Courage the Cowardly Dog?", "What is the name of the woman that lives with Courage?", "What is the name of the man that lives with Courage?"]
let answers = [["Purple","Grey","Orange"],["Muriel", "Angela", "Elizabeth"], ["Eustace", "Robert", "Ezio"]]
//Variables
var currentQuestion = 0
var rightAnswerPlacement:UInt32 = 0
var points = 0
//Label
#IBOutlet weak var lbl: UILabel!
//Button
#IBAction func action(_ sender: AnyObject) {
if (sender.tag == Int(rightAnswerPlacement))
{
print ("RIGHT!")
points += 1
}
else
{
print ("WRONG!!!!!!")
}
if (currentQuestion != questions.count)
{
newQuestion()
}
else{
performSegue(withIdentifier: "showScore", sender: self)
}
}
override func viewDidAppear(_ animated: Bool) {
newQuestion()
}
//Function that displays new question
func newQuestion(){
lbl.text = questions[currentQuestion]
rightAnswerPlacement = arc4random_uniform(3)+1
//Create a button
var button:UIButton = UIButton()
var x = 1
for i in 1...3
{
//Create a button
button = view.viewWithTag(i) as! UIButton
if (i == Int(rightAnswerPlacement))
{
button.setTitle(answers[currentQuestion][0], for: .normal)
}
else
{
button.setTitle(answers[currentQuestion][x], for: .normal)
x = 2
}
}
currentQuestion += 1
}
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.
}
}
Did you create UI Button in your Story Board ??
In your youtube video, watch 1:45
And remember to set your 3 UI Button's tag to 1, 2 and 3
watch 3:20
Your problem occurs because you've set your View's tag = 1.
You can fix it easily by change View's tag value to a number != 1, 2 and 3
Because your ViewController have 2 view with the same tag = 1. (view and UI Button).
So when you use view.viewWithTag(i), It accidentally select view not UI Button. So it can not convert to UI Button type
P/s: next time, if you want to select your Button directly, you can make an #IBOutlet for that Button as you make with your Label. It will not cause confusing error like that

Resources