简体   繁体   中英

cellForRowAtIndexPath not called after reloadData but numberOfRowsInSection does

In my current project I'm trying to fetch news from a REST-Endpoint and I wanna refresh the UITableView once the network request is finished. So I call reloadData() but unfortunately cellForRowAtIndexPath isn't called however numberOfRowsInSection gets called and returns the correct number of items.

Following my code stripped down to the relevant parts:

class NewsTableViewController: UIViewController {

    private var newsItems: Array<NewsItem>!
    private var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        newsItems = []
        addDummyItem()
        prepareTableView()
        getNews()
    }

    func addDummyItem(){
        let newsItem = NewsItem()
        newsItem.dateString = "12th May"
        newsItem.title = "Lorem ipsum"
        newsItem.imgUrl = "URL"
        newsItem.url = "URL"
        newsItem.message = "Lorem ipsum dolor sit amet"
        self.newsItems.append(newsItem)
    }

    func getNews(){
        let url = NSURL(string: "http://someurl.com/news")
        let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: url!)
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithRequest(urlRequest) { data, response, error in
            guard data != nil && error == nil else {
                print(error)
                return
            }

            guard let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200 else {
                print("status code not 200; \(response)")
                return
            }
            let json = String(data:data!, encoding: NSISOLatin1StringEncoding)
            let arr: AnyObject? = json?.parseJSONString
            for item in arr as! Array<AnyObject>{
                let newsItem = NewsItem()
                newsItem.dateString = (item["dateString"] as AnyObject? as? String) ?? ""
                newsItem.title = (item["title"] as AnyObject? as? String) ?? ""
                newsItem.imgUrl = (item["imgUrl"] as AnyObject? as? String) ?? ""
                newsItem.url = (item["url"] as AnyObject? as? String) ?? ""
                newsItem.message = (item["message"] as AnyObject? as? String) ?? ""
                self.newsItems.append(newsItem)
            }
            print("Network request finished - call reloadData()")
            dispatch_async(dispatch_get_main_queue(), {
               self.tableView.reloadData()
            })
        }
        task.resume()
    }

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        automaticallyAdjustsScrollViewInsets = false
    }

    private func prepareTableView() {
        tableView = UITableView()
        tableView.dataSource = self
        tableView.delegate = self
        tableView.separatorColor = UIColor.clearColor()
    }
}

extension NewsTableViewController : UITableViewDataSource{

    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print("Item count: ", newsItems.count)
        return newsItems.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        print("cellForRowAtIndexPath called with indexPathRow: ", indexPath.row)
        let cell = tableView.dequeueReusableCellWithIdentifier("ImageCardViewCell") as! NewsImageCardViewCell
        let item: NewsItem = newsItems[indexPath.row]
        getImageCardView(item.url, btnDate: item.dateString, textTitle: item.title, textDetail: item.message, imageCardView: cell.imageCardView, imageName: "news_1", indexPath: indexPath)
        return cell
    }
}

extension NewsTableViewController : UITableViewDelegate{
    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        tableView.deselectRowAtIndexPath(indexPath, animated: true)
    }
}

As you can see: The UITableView is correctly setup by setting the dataSource and delegate to my class. The reloadData() method is called on the main thread. Following the log-output:

Item count:  1
cellForRowAtIndexPath called with indexPathRow:  0
Network request finished - call reloadData()
Item count:  72

Note: At first there's one dummy item my array just to show you that cellForRowAtIndexPath is indeed called but only one time. After triggering reloadData() on numberOfRowsInSection is called but not the cellForRowAtIndexPath method.

I know that there're a lot of similar issues like this and I've checked them all for possible solutions but none were working. I appreciate any help.

Edit

Please note that the dummy view which is added before the network request is visible. So the UITableView s' height is not 0.

Edit #2

Thanks to everyone for your answers. I've found the issue. I've instantiated the ViewController via the Storyboard but I missed to set an IBOutlet . Due that the bounds of my UITableView were 0,0,0,0.

Check Following :

1 numberOfRowsInSection see the Number of return value

2 if step1 is called and return right value still not calling cellForRowAtIndexPath that means your table view height is less then height of cell or table view height is 0 , print tableview bounds and also check superview of tableview has clips to bounds to TRUE

That because your table view did not add to your window, If the table view is not visible, the UIKit will not deal with UI related methods. It's kind of Apple's lazy load .
Change your prepareTableView function as below:

private func prepareTableView() {
    tableView = UITableView(frame: self.view.bounds, style: .Plain)
    tableView.dataSource = self
    tableView.delegate = self
    tableView.separatorColor = UIColor.clearColor()
    self.view.addSubview(tableView)
}

tableview datasource method cellForRowAtIndexPath is depending on numberOfRowsInSection . So it may be possiblity that you having zero item in newsItems

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