numberOfRowsInSection 已调用但 cellForRowAt 未调用
Posted
技术标签:
【中文标题】numberOfRowsInSection 已调用但 cellForRowAt 未调用【英文标题】:numberOfRowsInSection called but cellForRowAt not called 【发布时间】:2021-05-27 13:31:02 【问题描述】:在我的应用程序中,我调用了一个 API 来获取一些数据并从中下载文件。下载后回调调用。在这种情况下,表格视图更新得很好。但是假设用户访问了屏幕并且在将内容下载回前一个屏幕并再次访问同一屏幕之前。在这种情况下,表视图未更新。仅当用户在未完成下载内容的情况下返回上一个控制器并再次出现在同一屏幕上时,我才会遇到此问题。
WarrantyVC.Swift
class WarrantyVC: UIViewController
// MARK: - Outlets
///
@IBOutlet weak var warrantyTableView: UITableView!
//Latum
///
@IBOutlet weak var knowMoreButton: UIButton!
// MARK: - Variables
///
var warrantyDataSource: WarrantyDataSource!
///
var viewModel: WarrantyViewModel?
// MARK: - Controller life cycle
///
override func viewDidLoad()
super.viewDidLoad()
setupUI()
getUserGuide()
///
deinit
viewModel = nil
// MARK: - Initializing UI methods
///
func setupUI()
viewModel = WarrantyViewModel()
warrantyDataSource = WarrantyDataSource(withTableView: warrantyTableView)
warrantyDataSource.delegate = self
// MARK: - API methods
///
func getUserGuide()
CommonMethods.showProgressHud(inView: self.view)
warrantyDataSource.introVideoAndGuideArray.removeAll()
viewModel?.getUserGuidefunc(userId: "\(DataManager.shared.user?.userId ?? 0)", motorId: selectedMotor?.MotorTypeId ?? 0,dmpModelId:selectedMotor?.dmpModelId ?? 0) [self] (success, response) in
CommonMethods.hideProgressHud()
Console.log(response ?? [String: Any]())
self.setupUI()
if !success /Show some message./
let userGuides = UserGuideService.introVideoAndGuideArray
if userGuides.count > 0
var newUserGuideArray = [UserGuide]()
for tempUserGuide in userGuides
let userGuide = tempUserGuide
let userManual = userGuide.usermanual
let videolink = userGuide.videolink
if videolink.trim().count > 0
if let tempUserGuide = userGuide.copy() as? UserGuide
tempUserGuide.usermanual = ""
tempUserGuide.videolink = videolink
newUserGuideArray.append(tempUserGuide)
if userManual.trim().count > 0
if let tempUserGuide = userGuide.copy() as? UserGuide
tempUserGuide.usermanual = userManual
tempUserGuide.videolink = ""
newUserGuideArray.append(tempUserGuide)
self.warrantyDataSource.introVideoAndGuideArray = newUserGuideArray
DispatchQueue.main.async
self.warrantyTableView.reloadData()
WarrantyDatasource.swift
protocol UserGuideDataSourceDelegate: class
///
func onOpenPDF()
///
func onPlayVideo(_ videoURL: String)
/// This DataSource class use to show data of UserGuide in table.
class WarrantyDataSource: NSObject
// MARK: - Variables
///
fileprivate let cellNibName = "warrantyCell"
///
var userGuideTitle: [String] = ["Intro to ABC", “XYZ”]
///
var userGuideImage: [UIImage] = [ imageLiteral(resourceName: "ic_play"), imageLiteral(resourceName: "ic_pdf")]
///
fileprivate let cellSpacingHeight: CGFloat = 12
///
var introVideoAndGuideArray = [UserGuide]()
///
weak var delegate: UserGuideDataSourceDelegate?
///
var numberOfSections: Int = 0
///
convenience init(withTableView tableView: UITableView)
self.init()
tableView.delegate = self
tableView.dataSource = self
///
@objc func onOpenPDF(_ sender: UIButton)
guard introVideoAndGuideArray.count > 0 else return
delegate?.onOpenPDF()
///
@objc func onPlayVideo(_ sender: UIButton)
delegate?.onPlayVideo(introVideoAndGuideArray[sender.tag].videolink)
/// This function help to setup user menual cell
///
/// - Parameters:
/// - cell: UserGuideCell
/// - indexPath: IndexPath
func setUserGuidePDFCell(_ cell: WarrantyCell, _ indexPath: IndexPath)
cell.guideImageView.image = imageLiteral(resourceName: "ic_default_pdf")
guard introVideoAndGuideArray.count > 0 else return
cell.guideLabel.text = introVideoAndGuideArray[indexPath.section].userGuideTitle
cell.guideButton.setImage(userGuideImage[1], for: .normal)
cell.guideButton.tag = indexPath.section
cell.guideButton.addTarget(self, action: #selector(onOpenPDF(_:)), for: .touchUpInside)
// MARK: - Extension Implementing UITableView DataSource Callbacks
///
extension WarrantyDataSource: UITableViewDataSource
// MARK: Extension Implementing UITableView DataSource methods
///
func numberOfSections(in tableView: UITableView) -> Int
numberOfSections = introVideoAndGuideArray.count
return introVideoAndGuideArray.count
///
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 1
/// Set the spacing between sections
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
return cellSpacingHeight
/// Make the background color show through
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?
let headerView = UIView()
headerView.backgroundColor = UIColor.clear
return headerView
///
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
guard let cell = tableView.dequeueReusableCell(withIdentifier: cellNibName, for: indexPath) as? WarrantyCell else return WarrantyCell()
if NetworkManager.sharedInstance.isReachable
let userGuide = introVideoAndGuideArray[indexPath.section]
if userGuide.videolink.trim().count > 0
cell.guideButton.setImage(userGuideImage[0], for: .normal)
cell.guideButton.tag = indexPath.section
cell.guideButton.addTarget(self, action: #selector(onPlayVideo(_:)), for: .touchUpInside)
cell.guideLabel.text = introVideoAndGuideArray[indexPath.section].videoTitle
let videoThumbnail = introVideoAndGuideArray[indexPath.section].vehicleVideoThumbnailLink
cell.guideImageView.kf.setImage(with: URL.init(string: videoThumbnail), placeholder: nil, options: nil, progressBlock: nil, completionHandler: nil)
else
setUserGuidePDFCell(cell, indexPath)
else
setUserGuidePDFCell(cell, indexPath)
return cell
【问题讨论】:
好吧,如果你弹出了一个 viewController,你应该取消正在运行的任务并在推送时再次调用 API,但是如果你正在持久化 API 结果,那么你可以在本地获取记录并在第二次推送时显示,如果是这样的话在需求范围内。 “数据没有重新开始下载”,它应该开始并且它不依赖于你之前的任务。您的代码中可能还有其他问题。 【参考方案1】:当您第一次调用 getUserGuide API 并且在获取回调之前或在下载数据之前,您会弹出视图控制器并在同一控制器上再次推送。第二次 getUserGuide API 将调用,您将从第一次调用 API 请求中获得回调。因此产生了这个问题。
您可以通过如下更改实现来解决此问题;
当第一次调用 API 并且在下载完成之前用户尝试弹出视图控制器暂停下载时,将响应中的 resumeData 存储在 userdefault 中。当用户第二次尝试调用 API 时,检查您已经启动下载的相同链接。如果然后通过从用户默认值中提取恢复数据来恢复相同链接的下载。
我希望这种方式对你有用。快乐编码。
【讨论】:
以上是关于numberOfRowsInSection 已调用但 cellForRowAt 未调用的主要内容,如果未能解决你的问题,请参考以下文章
未调用 cellForRowAtIndexPath 但调用 numberOfRowsInSection
cellForRowAtIndexPath 在比 numberOfRowsInSection 更晚被调用后崩溃
numberOfRowsInSection:未在 reloadData 上调用
未调用 cellForRowAt 但正在调用 numberOfSection 和 numberOfRowsInSection