使用 swift 单击按钮时在新视图中加载数据
Load data in new view when button is clicked with swift
我正在开发一个应用程序,我在其中以编程方式创建按钮。当我点击一个按钮时,它会从数据库中请求数据并在另一个视图中显示。
我用button.tag
来判断要请求什么数据,只有点击按钮才能获取tag
然而,当我点击按钮时,第一次没有任何显示。我必须再次点击它才能看到我想要的数据。
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])
}
}
和
@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
}
}
问题的最可能原因是您先调用 parseJson
,然后调用 prepareForSegue
。 parseJson
是异步的,在调用 prepareForSegue
之前您不会从服务中取回数据。第一步,将 prepareForSegue
移动到 parseJson
的完成块。
要跟进 ,您可能需要考虑以下其他一些步骤:
考虑使用自动布局代替 hard-coded 框架,这样您的 UI 将适应不同的大小 类。
考虑显示交互式列表(图像)的替代方法,而不是以编程方式添加按钮。例如,您可以使用原型(table 视图或集合视图)单元格。单元格是 selectable 并且可以代替按钮。其他好处包括:
- 一个可滚动的容器,如果您的按钮多于屏幕上显示的按钮。
- 单个 segue(或选择)由故事板原型单元处理,而不是需要让每个程序 "button" 执行一个 segue(或动作)。由于您知道选择了哪个单元格,因此不再需要标签来确定。
考虑将参数传递给目标视图控制器,而不是尝试在 prepareForSegue
中实例化和创建控件。此时未加载目标视图。
考虑让 UI 感觉响应更快,例如通过执行 segue 并显示占位符详细信息,然后您可以在网络请求完成后更新这些信息。否则,用户可能不得不在 segue 发生之前等待网络响应(这可能会让他们认为什么都没有发生并且不必要地再次点击,从而导致额外的网络请求)。
一般来说,Apple(或其他人)已经提供了一些方法来做你想做的事情,理想情况下可以减少你必须编写、调试、测试和维护的代码来完成你想要你的应用程序做的事情做。
我正在开发一个应用程序,我在其中以编程方式创建按钮。当我点击一个按钮时,它会从数据库中请求数据并在另一个视图中显示。
我用button.tag
来判断要请求什么数据,只有点击按钮才能获取tag
然而,当我点击按钮时,第一次没有任何显示。我必须再次点击它才能看到我想要的数据。
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])
}
}
和
@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
}
}
问题的最可能原因是您先调用 parseJson
,然后调用 prepareForSegue
。 parseJson
是异步的,在调用 prepareForSegue
之前您不会从服务中取回数据。第一步,将 prepareForSegue
移动到 parseJson
的完成块。
要跟进
考虑使用自动布局代替 hard-coded 框架,这样您的 UI 将适应不同的大小 类。
考虑显示交互式列表(图像)的替代方法,而不是以编程方式添加按钮。例如,您可以使用原型(table 视图或集合视图)单元格。单元格是 selectable 并且可以代替按钮。其他好处包括:
- 一个可滚动的容器,如果您的按钮多于屏幕上显示的按钮。
- 单个 segue(或选择)由故事板原型单元处理,而不是需要让每个程序 "button" 执行一个 segue(或动作)。由于您知道选择了哪个单元格,因此不再需要标签来确定。
考虑将参数传递给目标视图控制器,而不是尝试在
prepareForSegue
中实例化和创建控件。此时未加载目标视图。考虑让 UI 感觉响应更快,例如通过执行 segue 并显示占位符详细信息,然后您可以在网络请求完成后更新这些信息。否则,用户可能不得不在 segue 发生之前等待网络响应(这可能会让他们认为什么都没有发生并且不必要地再次点击,从而导致额外的网络请求)。
一般来说,Apple(或其他人)已经提供了一些方法来做你想做的事情,理想情况下可以减少你必须编写、调试、测试和维护的代码来完成你想要你的应用程序做的事情做。