I'm building a simple tic tac toe game and I would like to same each "X" or "O" in an array so that when the user leaves the screen and comes back the game reloads.
I can get it to print to the output screen but it doesn't show up in the IOS simulator. I've only have the first two squares coded because I was hoping to get the array to work before I moved on to the rest.
Here's my code:
import UIKit
var gamePieces3 = NSMutableArray()
class GameViewController3 : UIViewController {
#IBOutlet var button0 : UIButton !
#IBOutlet var button1 : UIButton !
#IBOutlet var spot0 : UIImageView !
#IBOutlet var spot1 : UIImageView !
#IBAction func addGamePiece0(button0 : AnyObject) {
if (goNumber % 2 == 0) {
let image2 = UIImage(named : "cross.png")
spot0.image = image2
}
else {
let image1 = UIImage(named : "circle.png")
spot0.image = image1
}
gamePieces3.addObject(spot0)
goNumber++
}
#IBAction func addGamePiece1(button1 : AnyObject) {
if (goNumber % 2 == 0) {
let image2 = UIImage(named : "cross.png")
spot1.image = image2
}
else {
let image1 = UIImage(named : "circle.png")
spot1.image = image1
}
gamePieces3.addObject(spot1)
goNumber++
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
override func viewDidAppear(animated : Bool) {
print(gamePieces3)
}
}
There are more things you need to implement in your code if you want your app to "remember" where it left off from last app close or exit. Since you only want to store which button location stores "cross" or "circle", I think most suitable and easy way to do is using NSUserDefaults. It works very similar to a Dictionary. You can put something like "Button0" all the way to "Button8" as keys, and "cross.png" or "circle.png" as value. Every time your gamePieces3 is changed, you need to change that NSUserDefaults accordingly. Then in you videDidLoad, you want to read from your NSUserDefaults. Scan through NSUserDefaults, and apply "cross.png" or "circle.png" accordingly to controller's view.
self.view.addSubview(<ImageView with your image>);
Related
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]
So right now I have code that makes a TapGestureRecognizer for each image in an array, and what I'm trying to do is return the index of the image that has been tapped by the user. What would be the easiest way to achieve this? I'm new to Swift so I got part of this from a youtube tutorial and I don't really understand how to use gesture recognizers :/
This is what I have so far (simplified to only include what is relevant):
import UIKit
class HomeViewController: UIViewController {
var recognizersAdded = false
#IBOutlet weak var right1: UIImageView!
#IBOutlet weak var right2: UIImageView!
#IBOutlet weak var right3: UIImageView!
override func viewDidLoad()
{
super.viewDidLoad()
var houseImages = [self.right1, self.right2, self.right3]
for imageview in houseImages
{
if !recognizersAdded
{
let recognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped))
imageview!.addGestureRecognizer(recognizer)
imageview!.isUserInteractionEnabled = true
}
}
recognizersAdded = true
}
#IBAction func imageTapped(recognizer: UIGestureRecognizer)
{
if let view = recognizer.view as? UIImageView
{
var i = 0
//set i to index of image tapped
advance4(index: i)
}
}
Since you already have an array storing all your images, it's fairly easy to know what image (and index) has been tapped by searching the image index within houseImages.
Because you don't need complex verifications to get your index with firstIndex(where: [...]), I would suggest to simply use firstIndex(of: UIImageView) in your case.
#IBAction func imageTapped(recognizer: UIGestureRecognizer) {
guard let tappedView = recognizer.view as? UIImageView else {
return
}
let index = self.houseImages.firstIndex(of: tappedView)
print("House image index = \(index)")
}
You can do this quite easily since you are already creating an array of UIImageView's and you just need the index of the tapped imageView within the array, you simply need to use the method firstIndex(where:, here is the code:
#IBAction func imageTapped(recognizer: UIGestureRecognizer) {
let houseImages = [self.right1, self.right2, self.right3]
if let view = recognizer.view as? UIImageView {
let indexOfSelectedImageView = houseImages.firstIndex(where: { $0 == view })
print(indexOfSelectedImageView)
}
}
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)
}
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
I'm trying change an uiimage control's containing image by clicking a button in swift. For this, i wrote a simple a "guess how many fingers i'm holding up" app. I've read some stackoverflow articles but couldn't solve the problem. Below you can see my code and my ui. How can i change change image on click?
Here's my code:
import UIKit
class ViewController: UIViewController {
#IBOutlet var myImageView: UIImageView!
#IBOutlet var inputField: UITextField!
#IBAction func clickedGuessButtonAction(sender: AnyObject) {
println("Guess button clicked")
var randomX = Int(arc4random()%6)
println("randomX = \(randomX)")
var guess = inputField.text.toInt();
let image0 = UIImage(named: "images/qm.jpg")
let image1 = UIImage(named: "images/tick.jpg")
let image2 = UIImage(named: "images/cross.jpg")
if((inputField.text) != nil){
if(guess == randomX){
println("correct")
myImageView.image=UIImage(named: "tick.jpg") // THIS IS NOT WORKING
myImageView.image=image1 // THIS IS NOT WORKING TOO
inputField.resignFirstResponder();// hides keyboard
}
else
{
println("wrong")
myImageView.image=UIImage(named: "cross.jpg")
inputField.resignFirstResponder();//hides keyboard
}
}
else{
println("invalid input. requires integer only")
inputField.resignFirstResponder();// hides keyboard
}
}
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.
}
}
And here's my UI:
You don't need to specify either the asset catalog's name or the image file's extension. Try removing those. For example,
myImageView.image = UIImage(named: "tick")
It may depend on the version of Xcode you are using. For me the following worked:
ImageView.image = UIImage(named: "Elephants.jpg")
In Swift:
myImageView = "nameOfImage";