从UIAlertAction处理程序更新UILabel在Swift 4中不起作用

时间:2019-06-04 22:38:40

标签: ios swift uitableview uialertcontroller uialertaction

我的iOS应用程序中有UITableView的子类(Swift 4,XCode 9)。该表有一行,我希望它在单击时显示警报,从用户那里获取一些输入,然后在用户单击警报中的“确定”时更新表中的标签(lblUserFromPrefs)。目前,一切正常,除了标签未更新。这是我的UITableView子类中的相关代码:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("Clicked section: \(indexPath.section) row: \(indexPath.row)")
    let alert = UIAlertController(title: "Username", message: "what is your name", preferredStyle: .alert)

    alert.addTextField { (textField) in
        textField.text = ""
    }
    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: { [weak alert] (_) in
        let textField = alert!.textFields![0]
        if let text = textField.text {
            print("Text field: \(text)")
            DispatchQueue.main.async {
                self.lblUserFromPrefs.text = text
                print("label updated")
            }
        }
    }))

    DispatchQueue.main.async {
        self.present(alert, animated: true, completion: nil)
    }
}

当我运行此命令时,会发生什么情况,即当警报关闭时,标签的文本不会更改,但是再次单击表行时,标签的文本会立即更改。我不知道为什么要等到再次单击该行以更新文本。我期望的所有打印语句都会打印(包括按下警报的“确定”按钮时立即打印“标签更新”),并且它们打印正确的内容。我知道,当您尝试从后台线程中的闭包更新UI时,必须使用DispatchQueue.main.async {},但是我不确定即使使用主线程也不能更新UI。我尝试使用DispatchQueue.main.async(execute: {})并将self.lblUserFromPrefs.setNeedsDisplay()直接放在self.lblUserFromPrefs.text = "text"之后。有什么想法我做错了吗?谢谢!

3 个答案:

答案 0 :(得分:0)

[weak self]添加到调度中,如下所示:

DispatchQueue.main.async { [weak self] in

}

答案 1 :(得分:0)

尝试这样的事情:

let alertController = UIAlertController.init(title: "Enter some text", message: nil, preferredStyle: .alert)
    alertController.addTextField { (textField) in

        // Text field configuration
        textField.placeholder = "Enter..."
        textField.text = ""
    }

    alertController.addAction(UIAlertAction.init(title: "Ok", style: .default, handler: { (action) in
        if (alertController.textFields?.first?.hasText)! {
            if let text = alertController.textFields?.first?.text {
                self.label.text = text // Update the value
            }
        } else {
            self.label.text = "" // Default value
        }
    }))

    self.present(alertController, animated: true, completion: nil) // Present alert controller

答案 2 :(得分:0)

这是您要实现的行为的示例代码。只需将警报控制器代码包含在didSelect中即可,您应该一切顺利!

import UIKit
import PlaygroundSupport

class MyViewController : UITableViewController {

  override func numberOfSections(in tableView: UITableView) -> Int {
    return 1
  }

  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
  }

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
    if cell == nil {
      cell = UITableViewCell()
    }
    cell!.textLabel?.text = "Hello World!"
    return cell!
  }

  override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    let cell = tableView.cellForRow(at: indexPath)
    cell?.textLabel?.text = "Hello Universe!"
  }
}