KamaKAzii KamaKAzii - 2 months ago 9
Swift Question

Creating and assigning CGRect to a UIView within a for loop

I am looping through a [UIView], setting their frames, then adding them as subviews to a UIScrollView. In the code I am assigning a random background colour so I can differentiate the views from each other for testing purposes:

for i in 0...questionViews.count - 1 {
let hue: CGFloat = CGFloat(arc4random() % 256) / 256
let saturation: CGFloat = CGFloat(arc4random() % 128) / 256 + 0.5
let brightness: CGFloat = CGFloat(arc4random() % 128) / 256 + 0.5

questionViews[i].backgroundColor = UIColor(hue: hue, saturation: saturation, brightness: brightness, alpha: 1)

questionViews[i].frame = CGRect(x: screen.width * CGFloat(i), y: 0, width: screen.width, height: screen.height)
questionsScrollView!.addSubview(questionViews[i])
}


However, if I loop through these and print them:

for i in 0...questionViews.count - 1 {
print(questionViews[i].frame)
}


the result will be:

(3000.0, 0.0, 375.0, 667.0)
(3000.0, 0.0, 375.0, 667.0)
(3000.0, 0.0, 375.0, 667.0)
(3000.0, 0.0, 375.0, 667.0)
(3000.0, 0.0, 375.0, 667.0)
(3000.0, 0.0, 375.0, 667.0)
(3000.0, 0.0, 375.0, 667.0)
(3000.0, 0.0, 375.0, 667.0)
(3000.0, 0.0, 375.0, 667.0)


Why does every CGRect have final value of x from the for-loop?

Edit:

The
questionViews
array is set in the init with just empty
CGRects
to begin with:

questionViews = [UIView](count: numberOfQuestions, repeatedValue: UIView(frame: CGRect()))

Answer

When creating an array with repeated values of a reference type , it only creates one item and points all indexes to that. So in your for loop you're acutely setting the frame of all indexes of that one UIView over and over again.

replace this:

questionViews = [UIView](count: numberOfQuestions, repeatedValue: UIView(frame: CGRect()))

with

var questionViews = [UIView]()
for _ in 0..<numberOfQuestions {
    questionViews.append(UIView(frame: CGRect()))
}