试图了解按钮行为

时间:2015-01-23 14:56:46

标签: ios swift

这是我的第一个项目,我尝试设置按钮标题一段时间后应该重置。 这是我的代码:

第一个(测试)片段只是尝试立即设置为“tapped”,然后在2秒后重置为“tap me”。 我所看到的是将按钮耗尽2秒,然后再次“点击我”!

    @IBOutlet weak var button1: UIButton!
@IBAction func button1Tapped(sender: UIButton) {
    sender.setTitle("tapped", forState: .Highlighted)
    NSThread.sleepForTimeInterval(2.0)
    sender.setTitle("tap me", forState: .Normal)
}

第二个例子是我真正想要的! 但由于某种原因,我立即在这里失败,因为警报根本没有出现!?

任何提示?

    @IBOutlet weak var button2: UIButton!
@IBAction func button2Tapped(sender: AnyObject) {
}

func isOK(sender:UIAlertAction!){
    button2.setTitle("tapped", forState: .Normal)
    NSThread.sleepForTimeInterval(2.0)
    button2.setTitle("tap me", forState: .Normal)
}

func isCancel(sender:UIAlertAction!){
}

@IBAction func button2Tapped(sender: UIButton) {
    let alert = UIAlertController(title: "Test", message: "button", preferredStyle: UIAlertControllerStyle.Alert)
    alert.addAction(UIAlertAction(title:"OK", style: UIAlertActionStyle.Default, handler: isOK))
    alert.addAction(UIAlertAction(title:"Cancel", style: UIAlertActionStyle.Cancel, handler: isCancel))
    self.presentViewController(alert, animated: true, completion: nil)
}

行, 我改变了这个:

    @IBOutlet weak var button1: UIButton!
@IBAction func button1Tapped(sender: UIButton) {
    sender.selected = true
    NSThread.sleepForTimeInterval(2.0)
    sender.selected = false
}
override func viewDidLoad() {
    super.viewDidLoad()
    button1.setTitle("tapped", forState: .Selected)
    button1.setTitle("tap me", forState: .Normal)
}

但它显示了相同的行为。 实际上它显示“轻拍”但只有当我一直按下时才会出现!?

2 个答案:

答案 0 :(得分:0)

首先,删除您编写的所有代码。相反,请使用我从Matt的答案中获取的代码。积分归他所有。这个功能需要延迟"某事的行动。

func delay(delay:Double, closure:()->()) {
dispatch_after(
    dispatch_time(
        DISPATCH_TIME_NOW,
        Int64(delay * Double(NSEC_PER_SEC))
    ),
    dispatch_get_main_queue(), closure)
}

现在创建一个@IBAction连接:

@IBAction func button(sender: AnyObject) {
// Okay, the button has been tapped
  button.setTitle("tapped", forState: .Normal)

// after two seconds...
  delay(2.0) {

// change the button's title:
  button.setTitle("tap here!", forState: .Normal)

  }
}

答案 1 :(得分:0)

您尝试的第一种方式的问题之一是,您只需为sender的两个不同状态设置标题:.Highlighted.Normal。如果您从未更改sender的状态,则您只会看到与其当前状态相关联的标题(默认情况下为.Normal)。

您可以两次更新相同状态的标题以获得所需的行为,或者您可以考虑使用按钮的.Selected状态,具体取决于应用程序的实现和按钮的使用情况。

// Call these two setTitle lines wherever you are instantiating your button
// or otherwise setting up your view:
sender.setTitle("tapped", forState: .Selected)
sender.setTitle("tap me", forState: .Normal)

// Somewhere else, you can call either of these:
sender.selected = YES // sender now shows "tapped"
sender.selected = NO  // sender now shows "tap me"

其次,我们需要解决您的线程问题。

在某些时候,主线程已被安排运行isOK方法中包含的代码。它还有计划更新UI的工作。您的主线程队列可能如下所示:

(0): __ execute isOK(..)
(1): __ do some other stuff
(2): __ update the UI
(3): __ do some other stuff

如果您在(0)中更新了用户界面,然后在(0)中再次更新了该用户界面,则系统将无法看到第一次更新,因为系统未被允许进展到(2)之间。当您NSThread.sleepForTimeInterval() (0)时,您正在推迟UI更新并冻结您的应用。

相反,您需要将睡眠放入不同的队列,然后在持续时间过后将以下命令注入主线程。

您可以通过几种方式完成此操作,但最简单的方法是使用GCD(Grand Central Dispatch)和dispatch_after

@IBAction func button1Tapped(sender: UIButton) {
  sender.selected = YES
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2.0 * Double(NSEC_PER_SEC))),
                 dispatch_get_main_queue(), ^{
    sender.selected = NO
  });
}