J.Doe J.Doe - 4 months ago 29
iOS Question

Creating buttons with a for loop? Swift

func makeAButton(){
var tag = 1

for post in postArray {

let cgX = CGFloat(post.x!)
let cgY = CGFloat(post.y!)

let button : DragImg = DragImg(frame: CGRect(x: cgX, y: cgY, width: 100, height: 100))

button.backgroundColor = UIColor.blueColor()
button.setTitle(post.user, forState: .Normal)
button.addTarget(self, action: #selector(self.buttonAction), forControlEvents: .TouchUpInside)
button.tag = tag
self.view.addSubview(button)

print(tag)

tag += 1
}

}


I've currently got 7 things in my post array, and when I print out the tag, I get the

1
2
3
... and so on up to 7.

Whats happening though is that at the 0th item in the aray, 1 button is being created. Then at the 1st, 2 are being created at that x/y, and it keeps going up and up until I'm getting 7 buttons right ontop of eachother.

Why is this the case? I thought here the for loop would say:

For each post in PostArray make a single button using the data from that item in the PostArray.

How might I change this to work as intended?

Edit: (Just posting everything I've got)

import UIKit

import Firebase

class testController: UIViewController {
@IBOutlet weak var button : UIButton!
@IBOutlet weak var textField: UITextField!

var colorsArray = [String]()
var currentX = CGFloat()
var currentY = CGFloat()
var postArray = [CirclePost]()

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
let position :CGPoint = touch.locationInView(view)

currentY = position.y
currentX = position.x

}
}

override func viewDidLoad() {
super.viewDidLoad()


DataService.ds.REF_BASE.child("Colors").observeEventType(.Value) { (snapshot: FIRDataSnapshot) in

if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {

self.postArray = []

for snap in snapshots {


if let x = snap.value!["x"] as? CGFloat, y = snap.value!["y"] as? CGFloat, color = snap.value!["color"] as? String {
let post = CirclePost(postKey: snap.key, user: color , x: x, y: y)

self.postArray.append(post)
print(self.postArray.count)
self.makeAButton()

}
}
}


}

}

func makeAButton(){

var tag = 1

for post in postArray {

let cgX = CGFloat(post.x!)
let cgY = CGFloat(post.y!)

// let button = DragImg()
let button : DragImg = DragImg(frame: CGRect(x: cgX, y: cgY, width: 100, height: 100))

button.backgroundColor = UIColor.blueColor()
button.setTitle(post.user, forState: .Normal)
button.addTarget(self, action: #selector(self.buttonAction), forControlEvents: .TouchUpInside)
button.tag = tag
self.view.addSubview(button)


tag += 1
}

}

func buttonAction(sender: UIButton!) {

let button = postArray[sender.tag - 1]
print(button.user)
print("Button tapped")
}



@IBAction func buttonPressed(sender: AnyObject) {

let ref = DataService.ds.REF_BASE.child("Colors").childByAutoId()

ref.child("color").setValue(textField.text)
ref.child("x").setValue(currentX)
ref.child("y").setValue(currentY)



}


}

Answer

Here's your issue:

for snap in snapshots {
...
    self.postArray.append(post)
    print(self.postArray.count)
    self.makeAButton()

You're adding a post to the array, then drawing the array (1 item). Then next time you add an additional post and then draw the array (2 items) and so on.

You need to move the call self.makeAButton() out of that for loop.