Swfit TableView load next page after scrolling to the last cell - uitableview

I have tableview controller. It gets data from the api and loads page 1.
I want to go the next page when I scroll the bottom of the current page.
Is there a way to implement this?
var currentPage = 1
func loadArticles(){
let url = "http://yazar.io/api/article/feed/" + String(currentPage)
Alamofire.request(.GET, url).responseJSON { (Request, response, json, error) -> Void in
if (json != nil){
var jsonObj = JSON(json!)
if let data = jsonObj["articles"].arrayValue as [JSON]?{
self.articles = data
self.tableView.reloadData()
self.view.hideLoading()
self.refreshControl?.endRefreshing()
}
}
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("MakaleCell") as MakaleTableViewCell
if (indexPath.row == self.articles!.count - 5) {
currentPage += 1
println(currentPage)
loadArticles(currentPage: currentPage)
}
cell.article = self.articles?[indexPath.row]
return cell
}

I have tryied this, it looks ok. Is that work for you ?
#IBOutlet weak var tableview: UITableView!
var datasource = Array<Int>()
override func viewDidLoad() {
super.viewDidLoad()
for i in 0...21
{
datasource.append(i)
}
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath)
{
if indexPath.row == datasource.count-1
{
var max = datasource.count;
for i in max...max+15
{
datasource.append(i)
}
self.tableview.reloadData()
}
}

Thanks everyone, extending data solved my problem...
self.articles?.extend(data)

Related

Limit the amount of cells shown in tableView, load more cells when scroll to last cell

I'm trying to set up a table view that only shows a specific amount of cells. Once that cell has been shown, the user can keep scrolling to show more cells. As of right now I'm retrieving all the JSON data to be shown in viewDidLoad and storing them in an array. Just for example purposes I'm trying to only show 2 cells at first, one the user scrolls to bottom of screen the next cell will appear. This is my code so far:
class DrinkViewController: UIViewController {
#IBOutlet weak var drinkTableView: UITableView!
private let networkManager = NetworkManager.sharedManager
fileprivate var totalDrinksArray: [CocktailModel] = []
fileprivate var drinkImage: UIImage?
fileprivate let DRINK_CELL_REUSE_IDENTIFIER = "drinkCell"
fileprivate let DRINK_SEGUE = "detailDrinkSegue"
var drinksPerPage = 2
var loadingData = false
override func viewDidLoad() {
super.viewDidLoad()
drinkTableView.delegate = self
drinkTableView.dataSource = self
networkManager.getJSONData(function: urlFunction.search, catagory: urlCatagory.cocktail, listCatagory: nil, drinkType: "margarita", isList: false, completion: { data in
self.parseJSONData(data)
})
}
}
extension DrinkViewController {
//MARK: JSON parser
fileprivate func parseJSONData(_ jsonData: Data?){
if let data = jsonData {
do {
let jsonDictionary = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String : AnyObject]//Parses data into a dictionary
// print(jsonDictionary!)
if let drinkDictionary = jsonDictionary!["drinks"] as? [[String: Any]] {
for drink in drinkDictionary {
let drinkName = drink["strDrink"] as? String ?? ""
let catagory = drink["strCategory"] as? String
let drinkTypeIBA = drink["strIBA"] as? String
let alcoholicType = drink["strAlcoholic"] as? String
let glassType = drink["strGlass"] as? String
let drinkInstructions = drink["strInstructions"] as? String
let drinkThumbnailUrl = drink["strDrinkThumb"] as? String
let cocktailDrink = CocktailModel(drinkName: drinkName, catagory: catagory, drinkTypeIBA: drinkTypeIBA, alcoholicType: alcoholicType, glassType: glassType, drinkInstructions: drinkInstructions, drinkThumbnailUrl: drinkThumbnailUrl)
self.totalDrinksArray.append(cocktailDrink)
}
}
} catch let error as NSError {
print("Error: \(error.localizedDescription)")
}
}
DispatchQueue.main.async {
self.drinkTableView.reloadData()
}
}
//MARK: Image Downloader
func updateImage (imageUrl: String, onSucceed: #escaping () -> Void, onFailure: #escaping (_ error:NSError)-> Void){
//named imageData because this is the data to be used to get image, can be named anything
networkManager.downloadImage(imageUrl: imageUrl, onSucceed: { (imageData) in
if let image = UIImage(data: imageData) {
self.drinkImage = image
}
onSucceed()//must call completion handler
}) { (error) in
onFailure(error)
}
}
}
//MARK: Tableview Delegates
extension DrinkViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return numberOfRows
return drinksPerPage
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = drinkTableView.dequeueReusableCell(withIdentifier: DRINK_CELL_REUSE_IDENTIFIER) as! DrinkCell
//get image from separate url
if let image = totalDrinksArray[indexPath.row].drinkThumbnailUrl{//index out of range error here
updateImage(imageUrl: image, onSucceed: {
if let currentImage = self.drinkImage{
DispatchQueue.main.async {
cell.drinkImage.image = currentImage
}
}
}, onFailure: { (error) in
print(error)
})
}
cell.drinkLabel.text = totalDrinksArray[indexPath.row].drinkName
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let image = totalDrinksArray[indexPath.row].drinkThumbnailUrl{
updateImage(imageUrl: image, onSucceed: {
}, onFailure: { (error) in
print(error)
})
}
performSegue(withIdentifier: DRINK_SEGUE, sender: indexPath.row)
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let lastElement = drinksPerPage
if indexPath.row == lastElement {
self.drinkTableView.reloadData()
}
}
}
I saw this post: tableview-loading-more-cell-when-scroll-to-bottom and implemented the willDisplay function but am getting an "index out of range" error.
Can you tell me why you are doing this if you are getting all results at once then you don't have to limit your display since it is automatically managed by tableview. In tableview all the cells are reused so there will be no memory problem. UITableViewCell will be created when it will be shown.
So no need to limit the cell count.
I dont now what you are doing in your code but:
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
let lastElement = drinksPerPage // no need to write this line
if indexPath.row == lastElement { // if block will never be executed since indexPath.row is never equal to drinksPerPage.
// As indexPath starts from zero, So its value will never be 2.
self.drinkTableView.reloadData()
}
}
Your app may be crashing because may be you are getting only one item from server.
If you seriously want to load more then you can try this code:
Declare numberOfItem which should be equal to drinksPerPage
var numberOfItem = drinksPerPage
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
//return numberOfRows
return numberOfItem
}
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.row == numberOfItem - 1 {
if self.totalDrinksArray.count > numberOfItem {
let result = self.totalDrinksArray.count - numberOfItem
if result > drinksPerPage {
numberOfItem = numberOfItem + drinksPerPage
}
else {
numberOfItem = result
}
self.drinkTableView.reloadData()
}
}
}

Load more options with UITableView

Trying to load my data in page using pagination, I've already seen many examples but all are in Objective-C and some questions are unanswered.
My code:
class testTableViewController: UITableViewController {
//MARK: - Properties -
var allObjectArray: NSMutableArray = []
var elements: NSMutableArray = []
var currentPage = 0 //number of current page
var nextpage = 0
var selectedRow = Int()
//MARK: - View Life Cycle -
override func viewDidLoad() {
super.viewDidLoad()
for var i = 1; i < 500; i++ {
allObjectArray.addObject(i)
}
elements.addObjectsFromArray(allObjectArray.subarrayWithRange(NSMakeRange(0, 30)))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source -
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return elements.count + 1
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
selectedRow = (tableView.indexPathForSelectedRow?.row)!
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var customCell = tableView.dequeueReusableCellWithIdentifier("cell")
customCell = UITableViewCell(style: .Default, reuseIdentifier: "cell")
customCell!.textLabel!.text = "cell - \(allObjectArray[indexPath.row])"
if indexPath.row == elements.count {
customCell?.textLabel?.textColor = UIColor.blueColor()
customCell?.textLabel?.text = "Load more..."
}
return customCell!
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
nextpage = elements.count
if indexPath.row == nextpage {
if indexPath.row == selectedRow {
currentPage++
nextpage = elements.count - 5
elements.addObjectsFromArray(allObjectArray.subarrayWithRange(NSMakeRange(currentPage, 30)))
tableView.reloadData()
}
}
}
}
I want this kind of output:
Tried to fetch selected index but it will return nil.
Create Outlets in Interface Builder for tableview and make two dynamic prototype cells give them identifiers make one cell with a button(your load more cell button)
Then create action with that button that will contain the logic to load more cells!!!
now see the snipet below for reference...
class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var tblDemo: UITableView!
var arForCells:NSMutableArray = NSMutableArray()
let simpleCellID = "SimpleCell"
let loadMoreCell = "LoadMoreCell"
override func viewDidLoad() {
super.viewDidLoad()
tblDemo.delegate = self
tblDemo.dataSource = self
arForCells = NSMutableArray(objects: "1", "2", "3", "4", "5", "6", "7", "8", "9", "10")
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arForCells.count + 1
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
if (indexPath.row == arForCells.count){
let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier(loadMoreCell, forIndexPath: indexPath)
return cell
}else {
let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier(simpleCellID, forIndexPath: indexPath)
let lblCounter = cell.viewWithTag(111) as! UILabel
lblCounter.text = arForCells.objectAtIndex(indexPath.row) as! String
return cell
}
}
#IBAction func loadMoreCells(sender: AnyObject) {
let newAr:NSArray = NSArray(objects: "1", "2", "3", "4", "5", "6", "7", "8", "9", "10")
arForCells.addObjectsFromArray(newAr as [AnyObject])
tblDemo.reloadData()
}}
as I have checked, It should give you the desired results.
You could also do the same in TableViewFooter.
To set "Load More.." text add a label with this text in a view having the same size of your tableViewCell. Then add this in your tableView footer. Add a (custom/transparent)button in footer view so when that touched it will load your main array with more data and then reload your tableView.
Hope this helps!
First of all, You don't have to use this:
selectedRow = (tableView.indexPathForSelectedRow?.row)!
in the didSelectRowAtIndexPath. You can use simply
selectedRow = indexPath.row
next, your logic for willDisplayCellAtIndexPath seems redundant if you want to have cell to tap on it. You can simply put the following in enter code here:
nextpage = elements.count
if indexPath.row == nextpage {
currentPage++
nextpage = elements.count - 5
elements.addObjectsFromArray(allObjectArray.subarrayWithRange(NSMakeRange(currentPage, 30)))
tableView.reloadData()
}
also, I am not sure why do you need nextpage = elements.count - 5 but I assume that you have reason behind this.
done it my self
import UIKit
class LoadMoreTableVC: UITableViewController {
//MARK: - Properties -
var allObjectArray: NSMutableArray = []
var elements: NSMutableArray = []
var currentPage = 0 //number of current page
var nextpage = 0
var totalElements = 500 //total elements
var elementAtOnePage = 30 //at one page
//MARK: - View Life Cycle -
override func viewDidLoad() {
super.viewDidLoad()
for i in 0 ..< totalElements {
allObjectArray.addObject(i+1)
}
elements.addObjectsFromArray(allObjectArray.subarrayWithRange(NSMakeRange(0, elementAtOnePage)))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
// MARK: - Table view data source -
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
let count = elements.count + 1
if count < allObjectArray.count
{
return count
}
else
{
return allObjectArray.count
}
}
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == elements.count {
loadDataDelayed()
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
cell.textLabel!.text = "\(allObjectArray[indexPath.row])"
if indexPath.row == elements.count {
cell.textLabel?.text = "Load more..."
}
return cell
}
func loadDataDelayed(){
currentPage += 1
elements.addObjectsFromArray(allObjectArray.subarrayWithRange(NSMakeRange(currentPage, elementAtOnePage)))
tableView.reloadData()
}
}
I have already done this is in swift.
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
if loading == true {
var endScrolling:CGFloat = scrollView.contentOffset.y + scrollView.frame.size.height
if(endScrolling >= scrollView.contentSize.height){
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "loadDataDelayed", userInfo: nil, repeats: false)
}
}
}
Please try this code.
And share your response.
Happy coding :)

How to retrieve continuous data from mysql

I'm trying to find tutorials or examples on how to load a tableView or collectionView for continuous scrolling.
For example, I have a database of over 1000 entries but I only want to fetch a 100 at a time. Then when the scroll reaches the bottom it automatically loads the next 100, and so on...
Does anyone know of any tutorials or examples?
I'm coding using swift 2 but any objective-C examples would be fine as I can usually figure out the translation.
I have created a test app to try it out. It fetches 20 records starting from zero.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet weak var personTable: UITableView!
var people = []
var startIndex:Int = 0;
override func viewDidLoad() {
super.viewDidLoad()
self.personTable.delegate = self
self.personTable.dataSource = self
fetchData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.people.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("personCell") as! TableViewCell
cell.usernameLabel.text = people[indexPath.row]["username"] as? String
return cell
}
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == people.count - 1{
self.startIndex += 20
fetchData()
}
}
func fetchData(){
let post = PostService()
let data = ["startIndex":String(self.startIndex),"limit":"20"]
let url = "http://**********/index.php?action=fetchPersonList"
post.post(data, url: url) { (succeeded, msg) -> () in
if succeeded{
if msg as! String != "<null>"{
self.people = msg as! NSArray
self.personTable.reloadData()
}
}
}
}
}
it works when the last cell is reached and reloads the data but doesn't stop until all the rows have been downloaded which is when it throws an error as there is no more data.
I'm not sure where to go from here.
I've looked for the last couple of hours online to try and find examples but either i'm not using the right search terms or there aren't that many out there.
After several hours of experimenting with this (that I was hoping to avoid by finding a tutorial which wasn't to be.) I eventually found a method that works.
This is the code that works for me.
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
#IBOutlet weak var personTable: UITableView!
var people = [NSDictionary]()
var page = 0
var holdPage = false;
override func viewDidLoad() {
super.viewDidLoad()
self.personTable.delegate = self
self.personTable.dataSource = self
fetchData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.people.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("personCell") as! TableViewCell
cell.usernameLabel.text = people[indexPath.row]["username"] as? String
return cell
}
func scrollViewDidScroll(scrollView: UIScrollView) {
let actualPosition:CGFloat = scrollView.contentOffset.y;
let contentHeight:CGFloat = scrollView.contentSize.height
let viewHeight:CGFloat = scrollView.frame.height
if (actualPosition + viewHeight >= contentHeight && self.holdPage == false && self.page < 3) {
self.holdPage = true //this is used to stop this if statement from running more than once.
self.page++
self.fetchData()
}
}
func fetchData(){
let post = PostService()
let startIndex = self.page * 20
let data = ["startIndex":String(startIndex),"limit":"20"]
let url = "http://*********/index.php?action=fetchPersonList"
post.post(data, url: url) { (succeeded, msg) -> () in
if succeeded{
if let data = msg as? [NSDictionary]{
self.people = self.people + data
self.holdPage = false
self.personTable.reloadData()
}
}
}
}
}
I had to use the holdPage variable as I found that when the scroll reached the end it loaded several pages in one go.
The only drawback to this method is that it keeps adding rows to the people array as you scroll down making it bigger each time. I was initially looking to remove the rows that were no longer in view but that was proving to be very complex.
Unless someone can show me a good example?

Loading an Array to TableView based on Segment-Control

I am relatively new to Swift. I tried to search and google the problem but i can't find any answers. It shouldn't be that hard. Hope you guys can help me out. I‘ve been struggling with this Issue over days now:
I created a Tableview which loads an array of tuples from another .swift file. That is working fine! Now I want the tableview to choose the .swift based on a "segment control". So if the Segment-Control is switched to "A" I want it to show the Array of "PSSCBOOKMac.Swift", for B it would be the Array of "PSSCBOOKWin.swift".
The Action ist written properly, I guess (print-statements are working). But the change of the segment-control doesn't effect the Tableview. My guess: The segment-control doesn't effect the Tableview because it has been loaded before and I can't change the value. How can I achieve that?
Cheers for any answers!
Here is the Code:
import UIKit
class ViewController: UIViewController, UITableViewDataSource {
#IBOutlet weak var PSSCSegmentControl: UISegmentedControl!
//LOAD ARRAY FROM PSSCBOOK.SWIFT
var PSSCBook = PSSCBOOKMac()
#IBAction func PSSCSegmentControlChoose(sender: AnyObject) {
if PSSCSegmentControl.selectedSegmentIndex == 0 {
var PSSCBook = PSSCBOOKMac()
println("im mac")
} else {
var PSSCBook = PSSCBOOKWin()
println("im win")
}
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return PSSCBook.PSSCTools.count
} else {
return PSSCBook.PSSCFile.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("PSCell", forIndexPath: indexPath) as! UITableViewCell
if indexPath.section == 0 {
let (shortCutTitle,shortCutKey) = PSSCBook.PSSCTools[indexPath.row]
cell.textLabel?.text = shortCutTitle
cell.detailTextLabel?.text = shortCutKey
} else {
let (shortCutTitle,shortCutKey) = PSSCBook.PSSCFile[indexPath.row]
cell.textLabel?.text = shortCutTitle
cell.detailTextLabel?.text = shortCutKey
}
/* var PSIcon = UIImage(named: "PSIcon")
cell.imageView?.image = PSIcon */
return cell
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0 {
return "Tools"
} else {
return "File"
}
}
}
When you update the datasource of your table view, it won't magically update itself.
You have to reload the table view for the changes to take place:
#IBAction func PSSCSegmentControlChoose(sender: AnyObject) {
if PSSCSegmentControl.selectedSegmentIndex == 0 {
var PSSCBook = PSSCBOOKMac()
println("im mac")
} else {
var PSSCBook = PSSCBOOKWin()
println("im win")
}
self.tableView.reloadData();
}
I spend the last two days trying to figure out what was wrong with my code. I implemented the suggested reloadData() without having errors. The println Values in the console change.. But the tableview just won't refresh. I really don’t know where else to look, is searched for hours. Could somebody please tell me what type of silly mistake I am doing? Thanks guys!
import UIKit
class ViewController: UIViewController, UITableViewDataSource {
//LOAD ARRAY FROM PSSHORTCUTSBOOK.SWIFT
var PSSCBook = PSShortCutsBook()
#IBOutlet weak var SCOutlet: UISegmentedControl!
#IBOutlet weak var SCtableviewOutlet: UITableView!
#IBAction func SCAction(sender: AnyObject) {
if SCOutlet.selectedSegmentIndex == 1 {
var PSSCBook = PSShortCutsBook()
println("There are \(PSSCBook.shortCutsPS.count) items in this Array")
self.SCtableviewOutlet.reloadData();
} else {
var PSSCBook = PSShortCutsBook2()
println("There are \(PSSCBook.shortCutsPS.count) items in this Array")
self.SCtableviewOutlet.reloadData();
}
}
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 2
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if section == 0 {
return PSSCBook.shortCutsPS.count
} else {
return PSSCBook.shortCutsPS2.count
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier("PSCell", forIndexPath: indexPath) as! UITableViewCell
if indexPath.section == 0 {
let (shortCutTitle,shortCutKey) = PSSCBook.shortCutsPS[indexPath.row]
cell.textLabel?.text = shortCutTitle
cell.detailTextLabel?.text = shortCutKey
} else {
let (shortCutTitle,shortCutKey) = PSSCBook.shortCutsPS2[indexPath.row]
cell.textLabel?.text = shortCutTitle
cell.detailTextLabel?.text = shortCutKey
}
/* var PSIcon = UIImage(named: "PSIcon")
cell.imageView?.image = PSIcon */
return cell
}
func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section == 0 {
return "Tools"
} else {
return "Help"
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

refreshing table while scrolling ios swift

I have tableView with custom cell. I load some information from the internet and add it to the table if user scroll table down. Problem: after loading information new cells sometimes rewrite old cells, and sometimes blank cells appears in this table while scrolling. There is my code:
var Bool canEdit = true
#IBOutlet var table : UITableView!
var eventList : [EventCell] = [] // EventCell - custom cell class
func addEventsAndRefresh() {
if (canEdit){
canEdit = false
HTTPManager.getEvents(isFuture: true, offset: eventList.count, didLoad: getEvents) //it creates url and call function "getEvents" after ending async request
}
}
func getEvents(response : NSURLResponse!, data : NSData!, error : NSError!) {
if ((error) != nil) {
HTTPManager.showErrorAlert()
} else {
var result = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSArray
for elementOfArray in result {
var cell : EventCell = table.dequeueReusableCellWithIdentifier("EventCell") as EventCell
... // parsing result to cell
eventList.append(cell)
}
table.reloadData()
canEdit = true
}
}
func tableView(tableView: UITableView!, numberOfRowsInSection section: Int) -> Int {
return eventList.count
}
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
return eventList[indexPath.row]
}
func scrollViewDidEndDragging(scrollView: UIScrollView!, willDecelerate decelerate: Bool) {
var currentOffset = scrollView.contentOffset.y;
var maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height;
if (maximumOffset - currentOffset <= -40.0 && canEdit) {
addEventsAndRefresh()
}
}
I got the same problem when I reused the cell variable as you do.
Try to not put your cells in a list but instead save your result list as an instance variable and get the objects by in index in cellForRowAtIndexPath function as shown below.
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
var cell : EventCell = table.dequeueReusableCellWithIdentifier("EventCell") as EventCell
var element = result[indexPath.row] as YourObject
//Do something with cell
return cell
}

Resources