leo*_*019 5 real-time uitableview ios swift swift3
我正试图每秒重新加载我的tableview.我现在重新加载tableview对象,但由于我Order在重新加载之前清除数组,因为索引超出范围而崩溃.
这是我目前的代码
var orders = [Order]()
override func viewDidLoad() {
super.viewDidLoad()
// table stuff
tableview.dataSource = self
tableview.delegate = self
// update orders
var timer = Timer.scheduledTimer(timeInterval: 4, target: self, selector: "GetOrders", userInfo: nil, repeats: true)
GetOrders()
}
func numberOfSections(in tableView: UITableView) -> Int {
if orders.count > 0 {
self.tableview.backgroundView = nil
self.tableview.separatorStyle = .singleLine
return 1
}
let rect = CGRect(x: 0,
y: 0,
width: self.tableview.bounds.size.width,
height: self.tableview.bounds.size.height)
let noDataLabel: UILabel = UILabel(frame: rect)
noDataLabel.text = "no orders"
noDataLabel.textColor = UIColor.white
noDataLabel.textAlignment = NSTextAlignment.center
self.tableview.backgroundView = noDataLabel
self.tableview.separatorStyle = .none
return 0
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return orders.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "OrderCell", for: indexPath) as! OrderCell
let entry = orders[indexPath.row]
cell.DateLab.text = entry.date
cell.shopNameLab.text = entry.shopname
cell.shopAddLab.text = entry.shopaddress
cell.nameClientLab.text = entry.clientName
cell.clientAddLab.text = entry.ClientAddress
cell.costLab.text = entry.Cost
cell.perefTimeLab.text = entry.PerferTime
cell.Shopimage.hnk_setImage(from: URL(string: entry.Logo))
return cell
}
Run Code Online (Sandbox Code Playgroud)
这是我如何从API获取数据:
func GetOrders (){
orders = []
// get data by Alamofire
let info = Order(shopname: shopname, shopaddress: shopaddr,
clientName: cleintName,ClientAddress: clientAddres, PerferTime: time,
Cost: subtotal , date : time , Logo : logoString ,id : id)
self.orders.append(info)
// some if statements
DispatchQueue.main.async {
self.tableview.reloadData()
}
Run Code Online (Sandbox Code Playgroud)
如果范围超出索引,则返回此处
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
let order = orders[indexPath.row]
guard orders.count > indexPath.row else {
print("Index out of range")
return
}
let storyboard = UIStoryboard(name: "Main", bundle: nil)
var viewController = storyboard.instantiateViewController(withIdentifier: "viewControllerIdentifer") as! OrderDetailsController
viewController.passedValue = order.id
self.present(viewController, animated: true , completion: nil)
}
Run Code Online (Sandbox Code Playgroud)
我不知道它是否有效,但不过试一试.
orders = [])数组,同时你之前的调用尝试重新加载tableview index out of range.更改您的GetOrders()函数,如下所示
func GetOrders (){
//orders = [] remove this line
// get data by Alamofire
// some if statements
DispatchQueue.main.async {
//empty your array in main queue most importantly just after getting data from API and just before appending new data's
orders = []
let info = Order(shopname: shopname, shopaddress: shopaddr, clientName: cleintName,ClientAddress: clientAddres, PerferTime: time,
Cost: subtotal , date : time , Logo : logoString ,id : id)
self.orders.append(info)
self.tableview.reloadData()
}
Run Code Online (Sandbox Code Playgroud)**在从API获取数据之后,在添加新数据之前,最重要的是清空主队列中的数组
如果它无法解决您的问题,As @ o15a3d4l11s2表示确保GetOrders()只有在收到上一次通话的响应后才会调用该功能
override func viewDidLoad() {
super.viewDidLoad()
tableview.dataSource = self
tableview.delegate = self
GetOrders()
}
func GetOrders (){
//orders = [] remove this line
// get data by Alamofire
// some if statements
DispatchQueue.main.async {
//empty your array in main queue most importantly just after getting data from API and just before appending new data's
orders = []
let info = Order(shopname: shopname, shopaddress: shopaddr, clientName: cleintName,ClientAddress: clientAddres, PerferTime: time,
Cost: subtotal , date : time , Logo : logoString ,id : id)
self.orders.append(info)
self.tableview.reloadData()
Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self. getOrder), userInfo: nil, repeats: false)
}
Run Code Online (Sandbox Code Playgroud)这是一个逻辑提议,用于刷新订单并远离超出限制的异常 - 让我们getOrders()只在完成时调度自己的下一个调用.这是一个例子:
func getOrders() {
asyncLoadOrders(onComplete: { loadedOrders
self.orders = loadedOrders
self.tableView.reloadData()
Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(self. getOrder), userInfo: nil, repeats: false)
}
}
Run Code Online (Sandbox Code Playgroud)
这个逻辑的想法是在订单真正加载后一秒钟,然后才会调用下一个getOrders.
请注意,可能需要包装表的重载(如在您的示例中) DispatchQueue.main.async
你之所以得到这个结果是indexOutOfRange因为你根据 api 响应每 4 秒修改一次数组。tableview dataSource同时,您尝试访问同一数组中的数据。
变化:1:
tableView DataSource为 api 响应创建一个单独的数组。
func getOrders() {
var tempOrdersList = [Order]()
// get data by Alamofire
let info = Order(shopname: shopname, shopaddress: shopaddr, clientName: cleintName,ClientAddress: clientAddres, PerferTime: time,Cost: subtotal , date : time , Logo : logoString ,id : id)
tempOrdersList.append(info)
// some if statements
DispatchQueue.main.async {
//Assign temporary array to class variable, which you are using as tableview data source.
self.orders = tempOrdersList
self.tableview.reloadData()
}
}
Run Code Online (Sandbox Code Playgroud)
变化2:
不要简单地每 4 秒触发一次 api。一旦收到 api 的响应就安排计时器。
func getOrders() {
var tempOrdersList = [Order]()
// get data by Alamofire
let info = Order(shopname: shopname, shopaddress: shopaddr, clientName: cleintName,ClientAddress: clientAddres, PerferTime: time,Cost: subtotal , date : time , Logo : logoString ,id : id)
tempOrdersList.append(info)
// some if statements
DispatchQueue.main.async {
//Assign temporary array to class variable, which you are using as tableview data source.
self.orders = tempOrdersList
self.tableview.reloadData()
timer = Timer.scheduledTimer(timeInterval: 4, target: self, selector: #selector(self. getOrder), userInfo: nil, repeats: false)
}
}
// Invalidate the timer at the view controller deinit
deinit {
timer.invalidate()
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2687 次 |
| 最近记录: |