简体   繁体   中英

numberOfRowsInSection called but cellForRowAt not called

In my application, I called one API for getting some of data and from that I am downloading files. After downloading callback called. In this case table view updated well. But suppose user visit the screen and before downloading content back to previous screen and again visit same screen. In that case table view not updated. I am facing this issue only when user back to previous controller without completing download content and come again on same screen.

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
    }
}

When you first time call getUserGuide API and before getting callback or before downloading data you pop view controller and push again on same controller. That time second time getUserGuide API will call and you will get callback from first time calling API request. Due to that this issue produced.

You can overcome this issue by changing your implementation as follows;

When API Calling first time and before downloading complete user try to pop view controller that time pause downloading, store resumeData from response in userdefault. and when user try to call API second time that time check for same link you have already initiated for downloading. If then resume download for the same link by extracting resume data from user defaults.

I hope this way will work for you. Happy Coding.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM