如何解决UITableView 上的用户交互阻止进程
我有一个 TabelViewController。 TableViewCells 中的数据正在通过 tableview.reloadData() 以高频率(假设为 10 Hz)更新。到目前为止,这有效。但是当我滚动 TableView 时,更新会暂停,直到用户交互结束。我的应用程序中的所有其他进程也都暂停了。我该如何解决这个问题?
这是一个示例 TableViewController。如果您在模拟器上运行它并检查调试区域内的输出,您会注意到,当您滚动并按住 tableview 时,不仅图形(这里是标签)的更新被暂停,而且通知也被暂停。如果你在另一个类中有一个进程,情况也是如此。
有趣的是,如果您与 MapView 交互,则不会出现这种进程阻塞。我在这里错过了什么?
import UIKit
class TableViewController: UITableViewController {
var text = 0
var timer = Timer()
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addobserver(self,selector: #selector(self.recieveNotification),name: NSNotification.Name(rawValue: "testNotificatiion"),object: nil)
scheduledTimerWithTimeInterval()
}
func scheduledTimerWithTimeInterval(){
timer = Timer.scheduledTimer(timeInterval: 1/10,target: self,selector: #selector(self.updateCounting),userInfo: nil,repeats: true)
}
@objc func updateCounting(){
text += 1
let userInfo = ["test": text]
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "testNotificatiion"),object: nil,userInfo: userInfo)
tableView.reloadData()
}
@objc func recieveNotification(notification: Notification){
if let userInfo = notification.userInfo! as? [String: Int]
{
if let recieved = userInfo["test"] {
print("Notification recieved with userInfo: \(recieved)")
}
}
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
return 10
}
override func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell: UITableViewCell?
cell = tableView.dequeueReusableCell(withIdentifier: "rightDetail",for: indexPath)
cell?.detailTextLabel?.text = String(text)
return cell!
}
}
解决方法
在滚动 UITableView
时不会触发计时器。查看爱斯基摩人奎因 (Quinn The Eskimo) 的答案 here。
将您的方法更改为这样,即使在滚动时也能正常工作。
func scheduleMyTimer() {
let t = Timer(timeInterval: 1.0,repeats: true) { _ in
self.updateCounting()
}
RunLoop.current.add(t,forMode: RunLoop.Mode.common)
}
当滚动 CoreLocation
时,UITableView
回调也不会触发。这是一个解决方法。
来自 CLLocationManagerDelegate
的文档:
Core Location 在 runloop 上调用你的委托对象的方法 来自您初始化 CLLocationManager 的线程。那 线程本身必须有一个活动的运行循环,就像在你的 应用的主线程。
所以我改变了 CLLocationManager
init:
class AppDelegate {
var lm = CLLocationManager()
}
为此:
class AppDelegate {
var lm: CLLocationManager!
var thread: Thread!
func didFinishLaunching() {
thread = Thread {
self.lm = CLLocationManager()
Timer.scheduledTimer(withTimeInterval: 1,repeats: true) { (_) in
// empty on purpose
}
RunLoop.current.run()
// If no input sources or timers are attached
// to the run loop,the run() method exits immediately,// so we add a Timer just before the call.
}
thread.start()
}
}
然后,即使在滚动时,委托回调也会继续触发。 This 回答有帮助。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。