【发布时间】:2018-01-30 16:04:54
【问题描述】:
view the video of problem here 我试图让我的无限滚动工作顺利,在我让它工作之前,当用户达到表中的某个项目计数时,它会加载其他项目,但在加载时会出现一个页脚活动指示器,然后消失并添加下一批行......我后来发现有点烦人......所以我想优化它。我希望 tableview 最初加载 100 个项目,然后当用户在第 10 行附近时,它将开始加载接下来的 100 个项目和行......事情是......每次它拨打电话时...... uitableview 有点挂起。 ..
我确实在这里消除了一些琐碎的代码,例如分段控件和字母按钮......等等,
// // VCrestlist.swift // AsyncUITableview
import UIKit
import Foundation
import Alamofire
import SwiftyJSON
import Parse
class VCrestlist: UITableViewController{
let PageSize = 80
var items:[RestsModel] = []
var isLoading = false
var letter = "ALL"
var online = false
var loaded = false
var bigviewforact:UIView = UIView(frame: UIScreen.main.bounds)
@IBOutlet var MyFooterView : UIView!
override func viewDidLoad() {
super.viewDidLoad()
self.MyFooterView.isHidden = true
createButtons()
// Load custom Xib RestCell
let nib = UINib(nibName: "RestCell", bundle: nil)
// register cell identifier with custom Xib RestCell
self.tableView.register(nib, forCellReuseIdentifier: "Cell")
tableView.dataSource = self
loadSegment(0, size: self.PageSize,argletter:"ALL",online:self.online)
self.ButtonsScrollView.isScrollEnabled = true
}
class DataManager {
func requestData(_ offset:Int, size:Int,letter:String,online:Bool, listener:@escaping ([RestsModel]) -> ()) {
DispatchQueue.global(qos: .background).async {
var letra = ""
print("el offest es \(offset) y el size es \(size)")
if (letter != "") {
letra = letter
} else {
letra = "ALL"
}
let cart = Cart.sharedInstance
Alamofire.request("https://www.getmedata.com/rests.php", parameters: ["offset": "\(offset)","size":"\(size)","letra":"\(letra)","online":"\(online)"]).authenticate(usingCredential: cart.credential).responseJSON() {
response in
if(response.result.value != nil) {
let jsonObj = JSON(response.result.value!);
let rests = jsonObj as JSON
// print(jsonObj);
//generate items
if let restsarray = rests["rests"].arrayValue as [JSON]? {
var arr = [RestsModel]()
//3
for restDict in restsarray {
let restName: String? = restDict["nombre"].stringValue
let restLOGO: String? = restDict["logo"].stringValue
let detURL: String? = restDict["url"].stringValue
let detProvincia: String? = restDict["provincia"].stringValue
let detHorario: String? = restDict["horario"].stringValue
let detDireccion: String? = restDict["direccion"].stringValue
let detTipoComida: String? = restDict["tipo_comida"].stringValue
let detTelefono: String? = restDict["telefono"].stringValue
let detidRest: String? = restDict["id"].stringValue
let detalleDelivery: String? = restDict["alldelivery"].stringValue
let detalleOrderOnline: String? = restDict["orderonline"].stringValue
let detalleReservaOnline: String? = restDict["reservasonline"].stringValue
let dethasSchedule: Bool? = restDict["hasSchedule"].boolValue
let detopenNow: Bool? = restDict["opennow"].boolValue
let detscheduleToday: String? = restDict["scheduleToday"].stringValue
let detscheduleTodayLiteral: String? = restDict["scheduleTodayLiteral"].stringValue
let emp_instagram: String? = restDict["emp_instagram"].stringValue
let emp_e_orderonline: String? = restDict["emp_e_orderonline"].stringValue
let emp_e_reservasonline: String? = restDict["emp_e_reservasonline"].stringValue
let emp_e_kids: String? = restDict["emp_e_kids"].stringValue
let emp_e_pickup: String? = restDict["emp_e_pickup"].stringValue
let emp_e_delivery: String? = restDict["emp_e_delivery"].stringValue
let emp_e_wifi: String? = restDict["emp_e_wifi"].stringValue
let emp_e_valet: String? = restDict["emp_e_valet"].stringValue
let emp_e_exterior: String? = restDict["emp_e_exterior"].stringValue
let emp_e_happyhour: String? = restDict["emp_e_happyhour"].stringValue
let emp_e_desayuno: String? = restDict["emp_e_desayuno"].stringValue
let emp_e_fumar: String? = restDict["emp_e_fumar"].stringValue
let emp_e_vinos: String? = restDict["emp_e_vinos"].stringValue
let emp_e_bar: String? = restDict["emp_e_bar"].stringValue
let emp_e_games: String? = restDict["emp_e_games"].stringValue
let rest = RestsModel(name: restName!,image:restLOGO!,detailURL:detURL!,provincia:detProvincia!,tipocomida:detTipoComida!,idRest:detidRest!,hasSchedule: dethasSchedule!,scheduleToday: detscheduleToday!,scheduleTodayLiteral: detscheduleTodayLiteral!,openNow: detopenNow!,allDelivery: detalleDelivery!,orderonline: detalleOrderOnline!,reservaonline: detalleReservaOnline!, instagram: emp_instagram!, emp_e_kids: emp_e_kids!, emp_e_pickup: emp_e_pickup!, emp_e_delivery: emp_e_delivery!, emp_e_wifi: emp_e_wifi!, emp_e_valet: emp_e_valet!, emp_e_exterior: emp_e_exterior!, emp_e_happyhour: emp_e_happyhour!, emp_e_desayuno: emp_e_desayuno!, emp_e_fumar: emp_e_fumar!, emp_e_vinos: emp_e_vinos!, emp_e_bar: emp_e_bar!, emp_e_games: emp_e_games!, horario: detHorario!, direccion: detDireccion! ,telefono: detTelefono!)
arr.append(rest)
}
print(arr)
//call listener in main thread
DispatchQueue.main.async {
listener(arr)
}
}
}
}
}
///
}
}
func loadSegment(_ offset:Int, size:Int,argletter:String,online:Bool) {
if (self.loaded == false) {
let act:UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: UIActivityIndicatorViewStyle.gray)
bigviewforact.addSubview(act)
act.center = bigviewforact.center
self.view.addSubview(bigviewforact)
self.view.bringSubview(toFront: bigviewforact)
act.hidesWhenStopped = true
act.startAnimating()
//self.bigviewforact.removeFromSuperview()
self.loaded = true
}
//if (!self.isLoading) {
// self.isLoading = true
//self.MyFooterView.isHidden = (offset==0) ? true : false
let manager = DataManager()
manager.requestData(offset, size: size,letter:argletter,online:online,
listener: {(items:[RestsModel]) -> () in
/*
Add Rows at indexpath
*/
for item in items {
self.tableView.beginUpdates()
let row = self.items.count
let indexPath = IndexPath(row:row,section:0)
self.items += [item]
self.tableView?.insertRows(at: [indexPath], with: UITableViewRowAnimation.fade)
self.tableView.endUpdates()
}
self.bigviewforact.removeFromSuperview()
self.isLoading = false
self.MyFooterView.isHidden = true
}
)
// }
}
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == items.count-70 {
loadSegment(items.count, size: PageSize,argletter:self.letter,online:self.online)
}
}
// MARK: Table view data source
override func numberOfSections(in tableView: UITableView?) -> Int {
return 1
}
override func tableView(_ tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {
return items.count
}
override func tableView(_ tableView: UITableView?, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 85;
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell : RestCell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! RestCell
// Pass data to Cell :) clean the mess at the View Controller ;)
cell.restData = items[indexPath.row]
cell.tag = indexPath.row
return cell
}
}
【问题讨论】:
-
您应该在开始新的加载之前检查您是否尚未加载。为什么这段代码被注释掉了?为了可读性,您还应该将代码拆分为多个类。为什么不将
json传递给RestsModel.init而不是将其解析到位?另外,我相信Alamofire调用主队列上的处理程序,因此解析已经在主队列上完成。 -
@Sulthan 你对 isLoading 检查是正确的.. 我确实错误地注释掉了.. 关于 json 解析.. 这是一些旧代码:D ...甚至认为我没有检查是否已经加载..所以它可以防止双重加载..我已经修复..但是一旦它发出呼叫,事情就会挂起..它会在一瞬间滞后 uitableview...
-
您是否尝试仅更新您的项目数组,然后在主线程上调用
tableView.reloadData?因此,只需删除beginUpdates和endUpdates并在您调用listener(arr)的任何位置重新加载表格。
标签: swift uitableview infinite-scroll