快速加载表格

时间:2018-11-11 15:20:11

标签: ios swift uitableview grand-central-dispatch

嗨,我的应用程序中的UI出现问题,我关闭了UITableView,这样它将显示屏幕的一半,并在viewDidLoad中设置tableView委托和dataSource。但是我的UI加载速度很慢,我尝试在请求中使用DispatchQueue,但没有任何效果。并尝试在tableView委托和数据源中使用DispatchQueue.global(qos:.background).async,显示UI并显示表视图,但警告说tableView委托和dataSource主要在主线程中运行。但是对象加载也很慢。谁能建议我该怎么办?

这是我的代码

let tableView: UITableView = {
    let view = UITableView()
    view.backgroundColor = .white
    view.layer.cornerRadius = 20
    return view
}()

这是我的函数,在viewDidLoad中调用

fileprivate func setupTableView() {
    DispatchQueue.main.async {
        self.tableView.delegate = self
        self.tableView.dataSource = self
        self.tableView.register(PrayerTimeViewCell.self, forCellReuseIdentifier: self.cellId)
        self.tableView.separatorColor = .clear
        self.tableView.backgroundColor = .clear
        self.tableView.rowHeight = 53
    }
}

这是我的请求代码

DispatchQueue.global(qos: .background).async {
            Alamofire.request(prayerUrl, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil).responseData(completionHandler: { (dataResponse) in
                if let err = dataResponse.error {
                    print("Failed to fetch data:", err)
                    return
                }

                guard let data = dataResponse.data else { return }

                do {
                    let prayerData = try JSONDecoder().decode(PrayerModel.self, from: data)

                    prayerData.items.forEach({ (item) in
                        let shubuh = Prayer(prayerName: "Shubuh", prayerIcon: #imageLiteral(resourceName: "PartlyCloudyNight"), prayerTime: item.fajr)
                        let dzuhur = Prayer(prayerName: "Dzuhur", prayerIcon: #imageLiteral(resourceName: "Sunny"), prayerTime: item.dhuhr)
                        let ashar = Prayer(prayerName: "Ashar", prayerIcon: #imageLiteral(resourceName: "PartlyCloudyDay"), prayerTime: item.asr)
                        let maghrib = Prayer(prayerName: "Maghrib", prayerIcon: #imageLiteral(resourceName: "Overcast"), prayerTime: item.maghrib)
                        let isya = Prayer(prayerName: "Isya", prayerIcon: #imageLiteral(resourceName: "Clear"), prayerTime: item.isha)
                        self.prayers.append(contentsOf: [shubuh, dzuhur, ashar, maghrib, isya])
                    })
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                } catch let decodeErr {
                    print("Failed to decode:", decodeErr)
                }
            })
        }

my tableView

1 个答案:

答案 0 :(得分:5)

从http请求中获取数据要花费一些时间,因此在http请求未完成之前,表视图将没有数据。在这种情况下,我建议编写没有任何DispatchQueue.main.async等的代码。

只需将其写入您的viewDidLoad函数:

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self
    tableView.register(PrayerTimeViewCell.self, forCellReuseIdentifier: cellId)
    tableView.separatorColor = .clear
    tableView.backgroundColor = .clear
    tableView.rowHeight = 53

    getPrayersData() // this is moment when you probably haven't got data yet
}

现在为getPrayerData()创建函数

func getPrayersData() {
    Alamofire.request(prayerUrl, method: .get).responseJSON { response in

        // this is moment when request is completed

        guard let data = response.data else {
            print("Failed to fetch data:", response.error)
            return 
        }

        do {
            let prayerData = try JSONDecoder().decode(PrayerModel.self, from: data)

            prayerData.items.forEach({ (item) in
                let shubuh = Prayer(prayerName: "Shubuh", prayerIcon: #imageLiteral(resourceName: "PartlyCloudyNight"), prayerTime: item.fajr)
                let dzuhur = Prayer(prayerName: "Dzuhur", prayerIcon: #imageLiteral(resourceName: "Sunny"), prayerTime: item.dhuhr)
                let ashar = Prayer(prayerName: "Ashar", prayerIcon: #imageLiteral(resourceName: "PartlyCloudyDay"), prayerTime: item.asr)
                let maghrib = Prayer(prayerName: "Maghrib", prayerIcon: #imageLiteral(resourceName: "Overcast"), prayerTime: item.maghrib)
                let isya = Prayer(prayerName: "Isya", prayerIcon: #imageLiteral(resourceName: "Clear"), prayerTime: item.isha)
                self.prayers.append(contentsOf: [shubuh, dzuhur, ashar, maghrib, isya])
            })

            self.tableView.reloadData()

        } catch {
            print("Failed to decode: \(error)")
        }
    }
}