View Controller can't access elements in arary - ios

I'm trying to create my first game in apples xcode program using swift code but I've come across a problem with Arrays. Here's the code:
//
// ViewController.swift
// War
//
// Created by grayson seymour on 5/13/16.
// Copyright © 2016 SanGames. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var firstCardImageView: UIImageView!
#IBOutlet weak var secondCardImageView: UIImageView!
#IBOutlet weak var playRoundButton: UIButton!
#IBOutlet weak var backgroundImageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.playRoundButton.setTitle("Play", forState: UIControlState.Normal)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func playRoundTapped(sender: UIButton) {
var cardNamesArray:[String] = ["card0", "card1", "card2", "card3", "card4", "card5", "card6", "card7", "card8", "card9"]
// Creates randomly generated number for first and second card
let randomCardFirst = Int(arc4random_uniform(10))
let randomCardSecond = Int(arc4random_uniform(10))
// checks to see what imageview to set for the cards
let firstCardString:String = self.cardNamesArray[randomCardFirst]
let secondCardString:String = self.cardNamesArray[randomCardSecond]
// sets randomly generated number to imageview for second and first card
self.firstCardImageView.image = UIImage(named: firstCardString)
self.secondCardImageView.image = UIImage(named: secondCardString)
}
}
I'm getting an error on line 39 & 40 or more specifically
let firstCardString:String = self.cardNamesArray[randomCardFirst]
let secondCardString:String = self.cardNamesArray[randomCardSecond]
The error I'm getting is
value of type View Controller has no member cardNamesArray
As I am very new to this language I have dabbled a little bit in the code to see if I could fix the problem but everything I do just creates another error. Any help would be very appreciated. Thanks!

Why do you call self before your variable (Because your class has no variable called cardNamesArray), this variable is inside your function (mean that it is not global), so shouldn't call self.
Replace
let firstCardString:String = self.cardNamesArray[randomCardFirst]
let secondCardString:String = self.cardNamesArray[randomCardSecond]
By
let firstCardString:String = cardNamesArray[randomCardFirst]
let secondCardString:String = cardNamesArray[randomCardSecond]
If you just want to use this cardNamesArray in your function, you can try this solution above.
If you want to use it multiple time inside your class, you can declare cardNamesArray as a global variable.

Related

Cannot use instance member 'generateRandomNumbers' within property initializer; property initializers run before 'self' is available

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView1: UITableView!
var array = generateRandomNumbers(size: 1000)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView1.delegate = self
tableView1.dataSource = self
// var array = self.generateRandomNumbers(size: 1000)
// lazy var array = generateRandomNumbers(size: 1000)
// print(array)
}
func generateRandomNumbers(size: Int) -> [Int] {
guard size > 0 else {
return [Int]()
}
let result = Array(0..<size).shuffled()
return result
}
You are asking var array to receive a "default" value from the function generateRandomNumbers(). The "default" value is set during the initialisation of the instance of your view controller, so before the instance exists, so before the generateRandomNumbers() function exists. The compiler doesn't know how to give a value to array before the instance has finished being created.
A workaround is to set a dummy default value, then change it during initialisation, like this:
#IBOutlet weak var tableView1: UITableView!
var array = [Int]() // This is an empty array, the compiler can create it before the generateRandomNumbers() is available
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
tableView1.delegate = self
tableView1.dataSource = self
...
array = generateRandomNumbers(size: 1000) // Now that all variables are initialised, you can change their values
Well, the basic answer is the concept of understanding.
var array = generateRandomNumbers(size: 1000)
When the code is compiled, it first tries to compile the variables first. So at that time, self isn't initiated. So, therefore, it doesn't recognize the method generateRandomNumbers. You get the error.
The best possible solution is actually using
lazy var array = generateRandomNumbers(size: 1000)
When you use lazy it doesn't try to initialize until it is needed. So they are skipped for the first time compilation.
If you don't need lazy simply you have to declare it in the viewDidLoad()
var array = [Int]()
override func viewDidLoad() {
super.viewDidLoad()
array = generateRandomNumbers(size: 1000)
}

Iphone App Swift main screen works. Aborts on the second page

I am extremely new to Swift. Before I go on to my issue, I would like to thank everyone that takes time out of their day to help solve issues people are having.
I have been experimenting with swift by making a pool calculator app. I have the basic function to figure out how much chlorine someone needs to put in the pool etc...
The main page is just a filler but then when I click "Pool Calculator" , it aborts and gives me the error " SignalBRT"
The code (sloppy as it is) works and i have been experimenting with just a simple addition app that works fine.
But for this one, the code works fine and it gives me an issue. Since it is the "SignalBRT" error, it is such a broad meaning to what the error would be and I do not know what is causing it. I feel like it could be the scrolling view that i added but before i added any functions, it scrolled up and down fine so my assumption would be the "CalculateChlorine" part of the code
Here is my code:
import UIKit
class ViewController: UIViewController {
// #IBOutlet var Number1: UILabel!
//#IBOutlet var Number2: UILabel!
//#IBOutlet var Field1: UITextField!
// #IBOutlet var Field2: UITextField!
#IBOutlet var VolOfpool: UITextField!
#IBOutlet var CurrentR: UITextField!
#IBOutlet var DesiredR: UITextField!
#IBOutlet var labelResult: UILabel!
var DefaultChlorineWeight: Float = 2.0// in oz
var CurrentReading: Float = 1.0
var DesiredReading: Float = 2.0
#IBAction func CalculateChlorine(sender: AnyObject) {
//let a = (Field1.text! as NSString).floatValue
//let b = (Field2.text! as NSString).floatValue
//let sum = a + b
// labelResult.text = "\(sum)"
let Volume = (VolOfpool.text! as NSString).floatValue
let CurrentReading = (CurrentR.text! as NSString).floatValue
let DesiredReading = (DesiredR.text! as NSString).floatValue
let resultForChlorine = (DefaultChlorineWeight * (Volume/10000) * ((DesiredReading - CurrentReading) / 1))
labelResult.text = "\(resultForChlorine)"
}
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.
}
}
here is my error:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate { // it says error SignalBRT here
kind of hard to see without a picture but the first screen of the app has a button called " Pool Calculator" where it sends it to another screen where the user would input the values . The second screen aborts and gives me the error.

NSUser defaults not saving correctly?

So recently I have been making a practice app that has a textfield and a label. When you enter something into the textfield and hit save it should change the label to that text and save it. The reason why it saves is so when you open the app the text of the label is equal to the last thing you saved. The text will save again if you hit save on a new string in the text box.
The problem I am having is that the label won't appear with text until you save something new and the string isn't saving so their is nothing there even if you saved something.
Here is my code from the ViewController.swift:
//
// ViewController.swift
// Help
//
// Created by Lucas on 9/30/15.
// Copyright (c) 2015 Lucas. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
#IBOutlet var Savedlbl: UILabel!
#IBOutlet var Textfield: UITextField!
#IBOutlet var Label: UILabel!
var current = ""
var Saved = ""
override func viewDidLoad() {
super.viewDidLoad()
let currentDefault = NSUserDefaults.standardUserDefaults()
Savedlbl.text = Saved
if(currentDefault.valueForKey("Saved") != nil)
{
self.Saved = currentDefault.valueForKey("Saved") as! NSString! as String
}
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func Set(sender: AnyObject) {
setall()
}
func setall()
{
current = Textfield.text!
Label.text = Textfield.text!
let currentDefault = NSUserDefaults.standardUserDefaults()
Saved = (currentDefault.valueForKey("saved") as? String)!
currentDefault.setValue(Saved, forKey: "saved")
Savedlbl.text = Textfield.text
currentDefault.synchronize()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
Here is where I think the problem is in the view did load that would make sense. When the app loads its not setting it to the last thing saved.
import UIKit
class ViewController: UIViewController {
#IBOutlet var Savedlbl: UILabel!
#IBOutlet var Textfield: UITextField!
#IBOutlet var Label: UILabel!
var current = ""
var Saved = ""
override func viewDidLoad() {
super.viewDidLoad()
let currentDefault = NSUserDefaults.standardUserDefaults()
Savedlbl.text = Saved
if(currentDefault.valueForKey("Saved") != nil)
{
self.Saved = currentDefault.valueForKey("Saved") as! NSString! as String
}
// Do any additional setup after loading the view, typically from a nib.
}
Thanks and let me know if you need any more info, I will provide it as fast as I can!
Don't use valueForKey/setValue:forKey:. Those are KVC methods. You want setObject:forKey: and objectForKey:.
Your problems are that you are doing things in the wrong order. In viewDidLoad you are setting the textfield before you have retrieved the value from user defaults and in setall you are re-saving the previously saved value, not the new value.
Try:
import UIKit
class ViewController: UIViewController {
var saved=""
var current=""
#IBOutlet var Savedlbl: UILabel!
#IBOutlet var Textfield: UITextField!
#IBOutlet var Label: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let currentDefault = NSUserDefaults.standardUserDefaults()
self.saved=currentDefault.stringForKey("Saved") ?? ""
self.Savedlbl.text=self.saved
}
#IBAction func Set(sender: AnyObject) {
setall()
}
func setall() {
self.current = self.Textfield.text!
self.Label.text = self.current
let currentDefault = NSUserDefaults.standardUserDefaults()
currentDefault.setObject(self.current,forKey:"Saved")
self.Savedlbl.text = self.Textfield.text
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Also, by convention variables should start with a lower case letter and classes with an upper case. I changed Saved to saved and Current to current but I didn't change the IBOutlets because you will need to remake the connection in IB for those, but you should.

accessing variables created in the override func viewDidLoad() { super.viewDidLoad() function outside that function in swift

import UIKit
class SecondViewController: UIViewController {
#IBOutlet weak var labelA: UILabel!
#IBOutlet weak var labelB: UILabel!
var dataPassed:String!
var secondDataPassed:String!
var newVar: String!
var newVar2: String!
override func viewDidLoad() {
super.viewDidLoad()
labelA.text = dataPassed
labelB.text = secondDataPassed
newVar = labelA.text
println(newVar)
}
println(newVar) *** I can't access newVar outside override func viewDidLoad() { - Gives "expected declaration" Its driving me crazy!!!***
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Is there any data in dataPassed? If you don't assign any String to your dataPassed variable, and then you assign newVar to dataPassed, newVar will have nothing to print.
Try:
import UIKit
class SecondViewController: UIViewController {
#IBOutlet weak var labelA: UILabel!
#IBOutlet weak var labelB: UILabel!
var dataPassed:String! = "Test."
var secondDataPassed:String!
var newVar: String!
var newVar2: String!
override func viewDidLoad() {
super.viewDidLoad()
labelA.text = dataPassed
labelB.text = secondDataPassed
newVar = labelA.text
println(newVar)
}
Secondly, it appears that you're trying to println again outside of the function. That isn't going to work, because viewDidLoad is essentially the "main method" of your app. You can create other functions that respond to button touches, etc... and run a println there, but because Swift code is executed functionally, the code you're executing has to be inside of a particular function. While you can declare variables, as you have, you can't perform actions such as printing them outside of a function, because then there's no order/method to the madness.
The only place where you can run Swift code on a standalone basis without functions is in a Swift Playground. In XCode you can select File -> New -> Playground to try this out.

How Do I Add UIViewController to UIScrollView in Swift

I want to have a UIScrollView of UIViewControllers. I tested the ScrollView and it works fine, except when I try to add the ViewControllers. The project builds fine, but I get a "fatal error: unexpectedly found nil while unwrapping an Optional value" error that points at the ViewController, particularly the line:
self.imageView.image = UIImage(named: self.image!)
However, when I inspect the object, I can see variables image and text have values in the ViewController. I'm using Xcode 6.3 Beta and building to iOS8.1 target.
Here's the code:
import UIKit
class ViewController: UIViewController {
//#IBOutlet weak var contentScrollView: UIScrollView!
#IBOutlet var contentScrollView: UIScrollView!
//test to make sure ScrollView functions
//let colors = [UIColor.redColor(),UIColor.blueColor(), UIColor.greenColor(), UIColor.whiteColor(), UIColor.blackColor(), UIColor.yellowColor()]
var frame = CGRectMake(0, 0, 0, 0)
var dataArray = [PostItem]()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var da = PostItem(text: "test 1", pic: "beans.jpg")
self.dataArray.append(da!)
da = PostItem(text: "test 2", pic: "coffee.jpg")
self.dataArray.append(da!)
da = PostItem(text: "test 3", pic: "coffeeCup.jpg")
self.dataArray.append(da!)
for index in 0..<self.dataArray.count{
self.frame.origin.y = self.contentScrollView.frame.size.height * CGFloat(index)
self.frame.size = self.contentScrollView.frame.size
self.contentScrollView.pagingEnabled = false
let tempPost = self.dataArray[index]
var vc = PostViewController()
vc.text = tempPost.postText
vc.image = tempPost.postImage
self.contentScrollView.addSubview(vc.view)
}
self.contentScrollView.contentSize = CGSizeMake(self.view.frame.size.width, CGFloat(self.dataArray.count) * self.contentScrollView.frame.height)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}}
And here is the code for the ViewController I want to add:
import UIKit
class PostViewController: UIViewController {
//let postItem
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var postToFBButton: UIButton!
#IBOutlet weak var postToTwitterButton: UIButton!
#IBOutlet weak var postText: UILabel!
var image:String?
var text:String?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.imageView.image = UIImage(named: self.image!)
self.postText.text = text!
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}}
The fix is to create the PostViewController through instantiateViewControllerWithIdentifier from storyboard, this way, it will have an imageView loaded from storyboard when its view is added to the scrollview.

Resources