This question already has answers here:
How to initialize properties that depend on each other
(4 answers)
Closed 6 years ago.
I'm stuck at a variable declaration in Swift 3. My code looks like this:
Beginning of code
// Letter Buttons
#IBOutlet weak var LetterOneButton: UIButton!
#IBOutlet weak var LetterTwoButton: UIButton!
#IBOutlet weak var LetterThreeButton: UIButton!
#IBOutlet weak var LetterFourButton: UIButton!
#IBOutlet weak var LetterFiveButton: UIButton!
// Word Fields
#IBOutlet weak var WordLetterOne: UILabel!
#IBOutlet weak var WordLetterTwo: UILabel!
#IBOutlet weak var WordLetterThree: UILabel!
#IBOutlet weak var WordLetterFour: UILabel!
#IBOutlet weak var WordLetterFive: UILabel!
// Counter
#IBOutlet weak var CounterLabel: UILabel!
// Skip Button
#IBOutlet weak var SkipButtonLabel: UIButton!
// Define Variables
var index: Int = 0
The error appears in the following line:
var labels: [UILabel] = [WordLetterOne, WordLetterTwo, WordLetterThree, WordLetterFour, WordLetterFive]
Error message is "Cannot use instance member 'WordLetterOne' within property initializer; property initializers run before 'self' is available". Afterwards, another string is declared without any problems.
var letters: [String] = ["A", "B", "C", "D", "E"]
End of code
And help is highly appreciated!
Edit:
self.lazy var labels: [UILabel] = [WordLetterOne, WordLetterTwo, WordLetterThree, WordLetterFour, WordLetterFive]
is giving the errors "Consecutive declarations on a line must be separated by ';'" and "Instance member 'WordLetterOne' cannot be used on type 'ViewController'"
Like it says: when the runtime builds the array initalizer, the properties you're trying to put in the array are not defined yet (because self is not ready yet).
Try to make the properties static (depends on your actual situation).
Or -- initialize the labels array in the init method.
The definition of letters is ok because "A", "B", etc are constants.
Related
These are my Outlets, how can I out all off these in an array?
#IBOutlet weak var progressBar1: UIProgressView!
#IBOutlet weak var progressBar2: UIProgressView!
#IBOutlet weak var progressBar3: UIProgressView!
#IBOutlet weak var progressBar4: UIProgressView!
Open the Assistant Editor, right-click and drag from one of your UIProgressView's or just drag from its "Referencing Outlet Collections" to the code file.
Insert outlet collection
Then you can drag from your swift file's #IBOutlet to the rest of your UIProgressView's. Add view to collection
On top declare a variable first like this
var outlets: [UIProgressView] = []
and now on ViewDidLoad method you can use this to put all outlets on that array
like this:
outlets = [progressBar1, progressBar2, progressBar3, progressBar4]
Hope you understand.
class ViewController: UIViewController {
#IBOutlet weak var p1: UIProgressView!
#IBOutlet weak var p2: UIProgressView!
#IBOutlet weak var p3: UIProgressView!
#IBOutlet weak var p4: UIProgressView!
var outlets: [UIProgressView] = []
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
outlets = [
p1,p2,p3,p4
]
}
}
If you have other types of views you can use
var outlets: [UIView] = [...]
As mentioned here Swift - IBOutletCollection equivalent you can use IBOutletCollection to do that. You can drag all your views to one IBOutlet array.
#IBOutlet weak var progressBars: [UIProgressView]!
For example, you can access the first progressBar like
progressBars[0]
But you have to careful about the order of progressBars, when you define IBOutletCollections the collection will not be order guaranteed. You can define the for each view and sort by their tags in runtime as mentioned here also Is IBOutletCollection guaranteed to be of correct order?
To order all views by their tags like
progressBars = progressBars.sorted { $0.tag < $1.tag }
In my app I currently have 9 labels on my storyboard, each showing a different value. (The values are stored in an array). As far as I know, each label has to be connected from the storyboard to the viewcontroller file separately, which makes my code look like this:
#IBOutlet weak var xValue: UILabel!
#IBOutlet weak var yValue: UILabel!
#IBOutlet weak var zValue: UILabel!
#IBOutlet weak var maxXValue: UILabel!
#IBOutlet weak var maxYValue: UILabel!
#IBOutlet weak var maxZValue: UILabel!
#IBOutlet weak var minXValue: UILabel!
#IBOutlet weak var minYValue: UILabel!
#IBOutlet weak var minZValue: UILabel!
And to set the values, I need to manually do:
xValue.text = arr[0]
yValue.text = arr[1]
...
minYValue = arr[7]
minZValue = arr[8]
Is there a way to connect multiple labels from the storyboard into an array so that I can simply do something like:
for i in 0...8 {
labelArray[i] = arr[i]
}
As rmaddy mentioned in a comment you can use an outlet collection:
#IBOutlet private var labels: [UILabel]!
Then in your storyboard labels will show up under Outlet Collections when right-clicking your ViewController, and you can link multiple labels:
You can put all the UILabel into an array, like this:
let labelArray = [xValue, yValue, zValue]
for i in 0..<labelArray.count-1{
labelArray[i] = arr[i]
}
Been getting this error whenever I have a variable or pretty much anything else. For example here I put cpuString and when I called it I got the error
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var cpuLabel: UILabel!
#IBOutlet weak var coolerLabel: UILabel!
#IBOutlet weak var moBoLabel: UILabel!
#IBOutlet weak var ramLabel: UILabel!
#IBOutlet weak var gpuLabel: UILabel!
#IBOutlet weak var psuLabel: UILabel!
#IBOutlet weak var caseLabel: UILabel!
var cpuString = ""
cpuSting = "Intel i5" // Here is where I got the Expected declaration
}
No idea whats causing this. Funny thing is that Xcode is ignoring everything. When I try to do something with the labels it's like there not even there. When I start typing and the auto complete suggestions for things to put in it doesn't have my variables or anything else listed.
You need to move that assignment either to declaration or into valid scope:
1:
var cpuSting = "Intel i5"
2:
override func viewDidLoad() {
super.viewDidLoad()
cpuSting = "Intel i5"
}
What you do in your code is essentially attempting to make an assignment in an improper place. If you declare a variable, then just declare it with required initial value. If you want to re-assign a value, then just do that in the right place, such as in instance method scope like viewDidLoad.
I would like my UIButtons to interact with each other - (With the corresponding button)
First set of buttons;
#IBOutlet var P1button1: UIButton!
#IBOutlet var P1button2: UIButton!
#IBOutlet var P1button3: UIButton!
#IBOutlet var P1button4: UIButton!
#IBOutlet var P1button5: UIButton!
#IBOutlet var P1button6: UIButton!
#IBOutlet var P1button7: UIButton!
#IBOutlet var P1button8: UIButton!
#IBOutlet var P1button9: UIButton!
Second set of buttons;
#IBOutlet var P2button1: UIButton!
#IBOutlet var P2button2: UIButton!
#IBOutlet var P2button3: UIButton!
#IBOutlet var P2button4: UIButton!
#IBOutlet var P2button5: UIButton!
#IBOutlet var P2button6: UIButton!
#IBOutlet var P2button7: UIButton!
#IBOutlet var P2button8: UIButton!
#IBOutlet var P2button9: UIButton!
In my code I apply an Image to one random P1button from an Array;
var buttons = [P1button1, P1button2, P1button3, P1button4, P1button5, P1button6, P1button7, P1button8, P1button9]
buttons.shuffleInPlace()
buttons[0].setImage(UIImage(named: "Green"), forState: .Normal)
Now, I want to know if there is a way to make the P2buttons "co-operate" with the P1buttons. Meaning that if an Image is applied to P1button1 then P2button1 is set to the same image! (and so forth for all buttons)
Example;
P2button1.setImage = UIImage(P1button1)
This obviously doesn't work but hopefully gives you a clue about what I'm trying to achieve.
One possible approach would be by subclassing UIButton. Perhaps something like this...
class TwinButton {
weak var twin: TwinButton?
}
Now, in your viewDidLoad method, link up all of the twins.
p1button1.twin = p2button1
p2button1.twin = p1button1
Now, I'd write a set of methods that have some "with twin" semantics...
extension TwinButton {
setWithTwin(title: String)
setWithTwin(backgroundImage: UIImage)
}
and those methods simply set the value on self and twin.
In my Swift app I have 9 outlets:
#IBOutlet weak var day1: UIImageView!
#IBOutlet weak var day1Title: UILabel!
#IBOutlet weak var day1Description: UILabel!
#IBOutlet weak var day2: UIImageView!
#IBOutlet weak var day2Title: UILabel!
#IBOutlet weak var day2Description: UILabel!
#IBOutlet weak var day3: UIImageView!
#IBOutlet weak var day3Title: UILabel!
#IBOutlet weak var day3Description: UILabel!
I'd like to "group" these together by their day using an integer as the key. So 1 maps to day1, day1Title, day1Description.
So that I could assign label text to each of the above generically rather than have to reference the specific image view, label, and description.
Any thoughts/suggestions?
I thought maybe:
Dictionary<int, Array<UIImageView, UILabel, UILabel>>
or
Dictionary<int, Array<UIView>>
but i'm not quite sure about this being the right move. Could I somehow assign a class that has 3 properties that reference these outlets maybe?
Or perhaps 3 outlet collections?
What do you think is good to do?
Thanks!
Why use a dictionary with an integer key? An array of 9 elements should work just as well. In addition, the value would be better represented as a tuple instead of as an array.
Array<(UIImageView, UILabel, UILabel)>
or
[(UIImageView, UILabel, UILabel)]
result
var views: [(UIImageView, UILabel, UILabel)]
…
views = [(day1, day1Title, day1Description),
(day2, day2Title, day2Description),
…
(day9, day9Title, day9Description)]
…
var (imageView, titleLabel, descriptionLabel) = views[dayNumber - 1]