I am developing an app, where I create buttons programmatically. When I click a button, it will request data from a database and show it in another view.
I use button.tag
to determine what data to request, and I can only get the tag once the button is clicked.
However when I click the button, it shows nothing the first time. I must click it again to see the data which I want.
override func viewDidLoad() {
super.viewDidLoad()
//parseJSON(tagId)
createButton()
// Do any additional setup after loading the view, typically from a nib.
}
func createButton(){
var j:CGFloat=60
for var i:Int = 0 ; i < myImages.count;i = i+1 {
let myButton = UIButton()
myButton.setImage(UIImage(named: "carasusto.jpg"), forState: UIControlState.Normal)
myButton.setTitleColor(UIColor.blueColor(), forState: .Normal)
myButton.frame = CGRectMake(j, j+60, 50, 50)
myButton.tag = i //assign a tag to every button
myButton.addTarget(self, action: "segueToCreate:", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(myButton)
j=j+60
print(myImages[i])
}
}
and
@IBAction func segueToCreate(sender: UIButton){
tagId = String(sender.tag)//tagId needs to fetch the information
parseJSON(tagId)
performSegueWithIdentifier("segueToView", sender:self)
}
func parseJSON(tagID:String){
Alamofire.request(.GET, "http://smarttags-001-site1.btempurl.com/SmartTagsRequests.aspx", parameters: ["AjaxFunc":"GetTagAttr","TagID":"\(tagID)"]).validate().responseJSON{ response in
switch response.result{
case .Success:
if let value = response.result.value {
let json = JSON(value)
print("JSON: \(json)")
self.TagName = json[0]["TagName"].stringValue
NSLog("\(self.TagName)")
self.ContentTitle = json[0]["ContentTitle"].stringValue
NSLog("\(self.ContentTitle)")
}
case .Failure(let error):
print(error)
}enter code here
}
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
var ViewTest : ViewTwo = segue.destinationViewController as! ViewTwo
var TagNameLabel = UILabel()
TagNameLabel.frame = CGRectMake(74, 112, 182, 64)
ViewTest.view.addSubview(TagNameLabel)
TagNameLabel.text = TagName
var ContentTitleLabel = UILabel()
ContentTitleLabel.frame = CGRectMake(74, 180, 182, 64)
ViewTest.view.addSubview(ContentTitleLabel)
ContentTitleLabel.text = ContentTitle
}
}
To follow up to MirekE's answer, here are some other steps you may want to consider:
Consider using Auto Layout in place of hard-coded frames, so your UI would adapt to different size classes.
Consider alternate approaches for showing an interactive list (of images) instead of programmatically adding buttons. For example, you could use a prototype (table view or collection view) cell. Cells are selectable and can take the place of a button. Other benefits include:
Consider passing parameters to your destination view controller, instead of trying to instantiate and create controls in prepareForSegue
. The destination's view is not loaded at that point.
Consider allowing the UI to feel more responsive, such as by performing the segue and showing placeholder details which you can then update once the network request completes. Otherwise, the user may have to wait for the network response before the segue occurs (which might make them think nothing happened and needlessly tap again, leading to an additional network request).
In general, Apple (or someone else) has already provided some way to do what you want, ideally leading to less code that you have to write, debug, test, and maintain to accomplish what you want your app to do.