Search code examples
iosiphoneuitableviewswiftalamofire

inserting row into UItableView error


I Have tableView that gived data from url api by 10 items. When it scroll to down I try to get next 10 items and insert them into row. So in viewDidload I get

 Alamofire.request(.GET, urlQuery, parameters: ["universityId": UBUniversitySettings.getUniversityId(), "page" : currentPage, "pageSize" : 10]).responseJSON{ (request, response, JSON, error) in
            println(JSON)
            var newsResponse = JSON! as NSArray
            for newsItemResponse in newsResponse{
                var newsItem:NewsModel = NewsModel()
                newsItem.newsImage = newsItemResponse.valueForKey("previewPic") as? String
                newsItem.newsTitle = newsItemResponse.valueForKey("title") as? String
                newsItem.newsDescription = newsItemResponse["content"] as? String
                newsItem.newsId = newsItemResponse["id"] as? String
                self.tableViewNews.addObject(newsItem)

               // self.newsTableView.reloadData()
                self.newsTableView.reloadSections(NSIndexSet.init(index: 0), withRowAnimation:UITableViewRowAnimation.Bottom )


            }
            self.currentPage = self.currentPage + 1

        }

and in

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    if(indexPath.row == self.currentPage * 10  - 1){
        self.getNextNews()
    }
}

i get next items

func getNextNews(){
    Alamofire.request(.GET, urlQuery, parameters: ["universityId": UBUniversitySettings.getUniversityId(), "page" : currentPage, "pageSize" : 10]).responseJSON{ (request, response, JSON, error) in
        println(JSON)
        var newsResponse = JSON! as NSArray
        if(newsResponse.count > 0){
            var newsIndex:NSInteger = 0
            var paths:NSMutableArray = NSMutableArray()
            for newsItemResponse in newsResponse{

                var newsItem:NewsModel = NewsModel()
                newsItem.newsImage = newsItemResponse.valueForKey("previewPic") as? String
                newsItem.newsTitle = newsItemResponse.valueForKey("title") as? String
                newsItem.newsDescription = newsItemResponse["content"] as? String
                newsItem.newsId = newsItemResponse["id"] as? String
                self.tableViewNews.addObject(newsItem)

                // self.newsTableView.reloadData()
                self.newsTableView.reloadSections(NSIndexSet.init(index: 0), withRowAnimation:UITableViewRowAnimation.Bottom )
                var indexPathVal = self.currentPage * 10 + newsIndex

                var indexPath = NSIndexPath(forRow: indexPathVal as Int, inSection: 0)
                paths.addObject(indexPath)
                newsIndex = newsIndex + 1

            }
            self.newsTableView.reloadData()
            self.newsTableView.beginUpdates()

            self.newsTableView.insertRowsAtIndexPaths(paths, withRowAnimation: UITableViewRowAnimation.Bottom)
            self.currentPage = self.currentPage + 1
            self.newsTableView.endUpdates()



        }

    }
}

But my app crashed and give me a message 

Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (11) must be equal to the number of rows contained in that section before the update (11), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'


Solution

  • After called self.newsTableView.reloadData() tableView already contains new data. And when you try make update: self.newsTableView.beginUpdates() //code self.newsTableView.endUpdates() Your array is not changed. You should not call reloadData or reloadSections while your array is updating(use insert with animation in the end of function, if you want). Or you should use reloadData or reloadSections without begin/end updates.

    Your method should be:

     func getNextNews(){
         Alamofire.request(.GET, urlQuery, parameters: ["universityId": UBUniversitySettings.getUniversityId(), "page" : currentPage, "pageSize" : 10]).responseJSON{ (request, response, JSON, error) in
             println(JSON)
             var newsResponse = JSON! as NSArray
             if(newsResponse.count > 0){
                 //code
                self.tableViewNews.addObject(newsItem)
    
                //self.newsTableView.reloadSections(NSIndexSet.init(index: 0), withRowAnimation:UITableViewRowAnimation.Bottom )
    
            }
            //self.newsTableView.reloadData()
            self.newsTableView.beginUpdates()
    
            self.newsTableView.insertRowsAtIndexPaths(paths, withRowAnimation: UITableViewRowAnimation.Bottom)
            self.currentPage = self.currentPage + 1
            self.newsTableView.endUpdates()
            }
        }
    }
    

    Or:

          func getNextNews(){
         Alamofire.request(.GET, urlQuery, parameters: ["universityId": UBUniversitySettings.getUniversityId(), "page" : currentPage, "pageSize" : 10]).responseJSON{ (request, response, JSON, error) in
             println(JSON)
             var newsResponse = JSON! as NSArray
             if(newsResponse.count > 0){
                 //code
                self.tableViewNews.addObject(newsItem)
    
                self.newsTableView.reloadSections(NSIndexSet.init(index: 0), withRowAnimation:UITableViewRowAnimation.Bottom )
    
            }
            self.newsTableView.reloadData()
            //self.newsTableView.beginUpdates()
    
            //self.newsTableView.insertRowsAtIndexPaths(paths, withRowAnimation: UITableViewRowAnimation.Bottom)
            self.currentPage = self.currentPage + 1
            //self.newsTableView.endUpdates()
            }
        }
    }