【问题标题】:Uitableview infinite scroll hang lagUitableview 无限滚动延迟
【发布时间】: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?因此,只需删除 beginUpdatesendUpdates 并在您调用 listener(arr) 的任何位置重新加载表格。

标签: swift uitableview infinite-scroll


【解决方案1】:

不要将每个项目插入 UITableView。将它们全部插入。

var indexPathes: [IndexPath] = []
var newItems: [RestsModel] = []
for item in items {
    let row = self.items.count
    let indexPath = IndexPath(row:row,section:0)
    newItems.append(item)
    indexPathes.append(indexPath)
}

self.items.append(contentsOf: newItems)
self.tableView.beginUpdates()
self.tableView?.insertRows(at: indexPathes, with: UITableViewRowAnimation.fade)
self.tableView.endUpdates()

【讨论】:

  • 刚刚尝试替换这部分代码并在 tableview.endUpdates() 上获得了 SIGABORt ... wierd..
  • 真的,您的解决方案非常有意义.. 我在 for 循环中调用 insertRows .. :/ 我想这是一个痛苦的过程 :lol .. 但现在 tihing 正在给予我一个错误..
  • 你能尝试在DispatchQueue.main.async {}块中做吗?
  • 您在控制台中收到什么消息并显示 SIGABORt 错误?
  • 用 dispatchque.main.sync 块尝试了整个块.. 仍然是 Thread 1: signal SIGABRT ,然后我在填充数组时尝试了 json 调用部分(我也有一个 main.sync阻止但确实删除了..所以我只是添加了..我没有得到 sigabort..但在 uitable 上没有显示任何内容... DispatchQueue.main.async { arr.append(rest) }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-31
  • 2011-01-11
  • 2012-08-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多