[英]How to find and set the text to UILabel of UITableViewCell in Swift?
[英]Set UILabel Text at Completion of CloudKit Asyncronous Operation in Swift
我是Swift和异步代码的新手,所以告诉我这是否可行。 基本上我想:
这本身显然没有用,但是作为一个原则,它将帮助我理解异步代码操作以及如何在完成操作时触发操作。
// In ViewController Swift file:
class ViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
readDatabase()
}
@IBOutlet weak var myLabel: UILabel!
}
let VC=ViewController()
//In Another Swift file:
func readDatabase() {
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "myRecord", predicate: predicate)
let container = CKContainer.default()
let privateDB = container.privateCloudDatabase
privateDB.perform(query, inZoneWith:nil) { (allRecs, err) in
VC.myLabel.text = ("\(allRecs?.count) records retreived")
/*
ERROR OCCURS IN LINE ABOVE:
CONSOLE: fatal error: unexpectedly found nil while unwrapping an Optional value
BY CODE LINE: Thread 8:EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
*/
}
}
我可以从viewDidLoad函数中设置文本字段,那么为什么不从该函数中调用的函数设置呢?
我尝试过的其他几件事:
这些都产生与上述相同的问题。
是的,我知道.perform中没有任何错误处理,是的,有记录。 如果在加载视图几秒钟后手动将UILabel文本的设置触发为记录计数,则可以正常工作。
因此,问题是...如何使用数据库的完成读取作为触发器将记录的属性加载到视图?
谢谢
问题出在这一行: let VC=ViewController()
。 在这里,您实例化了ViewController类的新实例,并尝试在该新创建的实例上设置标签。 但是,您需要在当前显示的viewController实例上设置标签。
只需将此行VC.myLabel.text = ("\\(allRecs?.count) records retreived")
self.myLabel.text = ("\\(allRecs?.count) records retreived")
VC.myLabel.text = ("\\(allRecs?.count) records retreived")
更改为self.myLabel.text = ("\\(allRecs?.count) records retreived")
,它应该可以正常工作。
知道了,解决方案如下所示:
// In ViewController Swift file:
typealias CompletionHandler = (_ recCount:Int,_ err:Error?) -> Void
class ViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
readDatabase(completionHandler: { (recCount,success) -> Void in
if err == nil {
self.myLabel.text = "\(recCount) records loaded"
} else {
self.myLabel.text = "load failed: \(err)"
}
})
}
@IBOutlet weak var myLabel: UILabel!
}
//In Another Swift file:
func readDatabase() {
let predicate = NSPredicate(value: true)
let query = CKQuery(recordType: "myRecord", predicate: predicate)
let container = CKContainer.default()
let privateDB = container.privateCloudDatabase
privateDB.perform(query, inZoneWith:nil) { (allRecs, err) in
if let recCount = allRecs?.count {
completionHandler(recCount,err)
} else {
completionHandler(0,err)
}
}
}
它和原始数据库之间的区别在于,此方法在函数调用中使用CompletionHandler类型别名来加载数据库记录,这将返回记录数和一个可选错误。
现在,完成操作可以存在于ViewController类中,并可以使用self.myLabel访问UILabel,它可以解决较早发生的错误,同时使数据库加载代码与ViewController类分开。
此版本的代码还具有基本的错误处理。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.