-1

I have quite a few similar UILabels I setup in code. In Objective-C I would do something like this (pseudo-code):

@property (nonatomic, strong) UILabel *l1, *l2, *l3, *l4, *l5, *l6, *l7, *l8, *l9;
...
l1 = [[UILabel alloc] init]; 
l2 = [[UILabel alloc] init];
l3 = [[UILabel alloc] init];
...
NSArray *lbls = @[l1, l2, l3, l4, l5, l6, l7, l8, l9];
for(UILabel *l in lbls) {
   l.textColor = [UIColor redColor];
   l.hidden = YES;
   ...
   [self.addSubview:l];
}

How would I do this in Swift? How can I pass the reference to a variable in a for in loop? The only option I found was to make a function with an inout parameter, but that splits my code into different areas.

Thanks

Joseph
  • 9,171
  • 8
  • 41
  • 67

3 Answers3

2

You do it in Swift exactly the same way you do it in Objective-C:

let lbls = [l1, l2, l3, l4, l5, l6, l7, l8, l9]
for l in lbls {
   l.textColor = .red
   l.isHidden = true
   self.addSubview(l)
}

This works the same way it did in Objective-C because UILabel is a class, which is a reference type. This means that, in a very real sense, l is a pointer every bit as much in Swift as in Objective-C (where the pointer-ness is made explicit by the UILabel* syntax).


Extra Credit

On the other hand, as long as you didn't intend to write all those changes back into lbls, you could also make this work even if this were a value type. You would have to assign l into a var inside the loop in order to change it.

So, let's suppose for purposes of illustration that we have a struct here. Then you would say:

let myArrayOfStructs = [l1, l2, l3, l4, l5, l6, l7, l8, l9]
for s in myArrayOfStructs {
   var s = s // make a version of `s` we can modify
   s.someProperty = newValue
   self.someMethod(s)
}

But, as I say, this would not write back the changes into the contents of the original array. Still, if your only purpose is to configure each s and then hand it off to some other method, you might not care about that.

Community
  • 1
  • 1
matt
  • 515,959
  • 87
  • 875
  • 1,141
1

It can be pretty much exactly the same.

I would do it this way...

labels.forEach {
    $0.backgroundColor = .red
    view.addSubview($0)
}
Fogmeister
  • 76,236
  • 42
  • 207
  • 306
1

Why have 9 different variables to hold the labels? You can start with all of them in an array and refer to them as labels[0], labels[1], ... , labels[8] when you need to access them individually:

// Create 9 UILabels and store them in [UILabel]
var labels = (1...9).map { _ in UILabel() }

...

for l in labels {
    l.textColor = .red
    l.isHidden = true
    self.addSubview(l)
}
vacawama
  • 150,663
  • 30
  • 266
  • 294
  • good point. where as matt's answer answers my original question - I will go forward with this solution. +1 – Joseph Jan 23 '17 at 07:10