Load more UICell in the bottom of the UITableView - ios

I started an iOS project and I'm working with UITableView to display a list of pilots with images . I did pagination on my api and I tried to load more once you scrolled the tableview. the problem that I got is that the new cells are always displayed on top of the tableview not in the bottom. Please check on my code if there is a solution I will be grateful
- (void)loadData :(NSInteger)page {
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
url = [NSURL URLWithString:[NSString stringWithFormat:#"%#%#%#%ld",NSLocalizedString(#"get_pilots",nil),mainDelegate.idAccount,#"?page=",(long)page]];
task = [restObject GET:url :mainDelegate.token completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSMutableDictionary* jsonResponse = [NSJSONSerialization
JSONObjectWithData:data
options:kNilOptions
error:nil];
NSArray *pilotKey = [jsonResponse objectForKey:#"pilot"];
for (NSDictionary *pilotItem in pilotKey ){
PilotObject *pilotObj = [PilotObject new];
[pilotObj getPilot:pilotObj :pilotItem];
[_pilotsAll addObject:pilotObj];
}
dispatch_async(dispatch_get_main_queue(), ^{
[hud hideAnimated:YES];
[self checkTableView:_pilotsDisplay :self.view];
[viewPilots.tableViewPilots reloadData];
});
}];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (currentPage == totalPages) {
return [_pilotsDisplay count];
}
return [_pilotsDisplay count] + 1;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == [_pilotsDisplay count] - 1 && currentPage<totalPages ) {
[self loadData:++currentPage];
NSLog(#"current page : = %ld",(long)currentPage);
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row == [_pilotsDisplay count]) {
static NSString *identifier = #"PilotCellTableViewCell";
PilotCellTableViewCell *cell = (PilotCellTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
cell.hidden=YES;
UIActivityIndicatorView *activityIndicator = (UIActivityIndicatorView *)[cell.contentView viewWithTag:100];
[activityIndicator startAnimating];
return cell;
} else {
PilotObject *pilotObjDisplay = nil;
pilotObjDisplay = [_pilotsDisplay objectAtIndex:[_pilotsDisplay count]-1-indexPath.row];
static NSString *identifier = #"PilotCellTableViewCell";
PilotCellTableViewCell *cell = (PilotCellTableViewCell *)[tableView dequeueReusableCellWithIdentifier:identifier];
cell.hidden=NO;
cell.image.image = pilotObjDisplay.imageDisplayPilot;
cell.titleLabel.text = pilotObjDisplay.firstName;
cell.subTitleLabel.text = pilotObjDisplay.lastName;
cell.backgroundColor = [UIColor colorWithHexString:NSLocalizedString(#"gray_background", nil)];
return cell;
}
return nil;
}

Why you are taking 2 array _pilotsDisplay and _pilotsAll ?
If not necessary then you can also do pagination using one NSMutableArray which you can use in both cases while fetching data from server as well as while filling data to UITableView.
Remember one thing only initialise your NSMutableArray in viewDidLoad method. And when you received new data use addObject method of NSMutableArray which you are already using. And then call reloadData method of UITableView.
And in cellForRowAtIndexPath don't use calculation like [_pilotsDisplay count]-1-indexPath.row, simply use indexPath.row.

Here, inserting rows to the tableview may help you.
[tableView beginUpdates];
NSArray *paths = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:[dataArray count]-1 inSection:1]];
[[self tableView] insertRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationTop];
[tableView endUpdates];

You shouldn't add cells to a tableview. what you should do is add data to the tableview's datasource (in your case, _pilotsDisplay) and then simply reload the table. If you want the new data to appear at bottom or in any particular order, you should do that to your datasource (the array).

Related

Buggy swipe to delete display on one more row after each delete

I'm having a weird issue on UITableView delete action since iOS 11.
Here's the relevant TableView code :
#implementation ChatMessageListViewController(TableView)
#pragma mark - table view datasource/delegate
- (NSArray<UITableViewRowAction *> *) tableView:(UITableView *)tableView editActionsForRowAtIndexPath:(nonnull NSIndexPath *)indexPath{
NSMutableArray *rowActions = [NSMutableArray array];
UITableViewRowAction *delete = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:#"Delete" handler:^(UITableViewRowAction * _Nonnull action, NSIndexPath * _Nonnull indexPath) {
[self deleteMessageAtIndexPath:indexPath];
}];
delete.backgroundColor = [UIColor redColor];
[rowActions addObject:delete];
return [rowActions copy];
}
- (void) deleteMessageAtIndexPath:(NSIndexPath *)indexPath {
NSString *threadID = [[self.messageArray objectAtIndex:indexPath.row] objectForKey:#"threadID"];
[self.tableView beginUpdates];
[self.messageArray removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
#weakify(self);
[UIUtil showLoadingHudWithText:WELocalString(#"message_remove_thread_loading_text", #"Deleting...", #"删除中...")];
[[AsyncUtil sharedInstance] dispatch_background_network:^{
DBManager *db = [[DBManager alloc] init];
[db deletetableData:[NSString stringWithFormat:#"singleChat WHERE threadID = '%#' ",threadID] ];
[[MemChatThreadMessages sharedInstance] removeThread:threadID];
NSDictionary * result = [Network deleteChatThread:threadID forEmail:[WEUtil getEmail]];
[[AsyncUtil sharedInstance] dispatch_main:^{
[UIUtil hideLoadingHuds];
#strongify(self);
if(self == nil) return ;
if([result[#"result"] isEqualToString:#"success"]){
}else{
[UIUtil showErrorMessage:WELocalString(#"message_remove_thread_error", #"Cannot delete this thread", #"不能删除该会话!")];
}
[self.tableView reloadData];
}];
}];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [self.messageArray count];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *messageInfo = [self.messageArray objectAtIndex:indexPath.row];
if ([(NSString *)[messageInfo objectForKey:#"isAnnouncement"] isEqualToString:#"1"]) {
return 80;
}else if ([[messageInfo objectForKey:#"chatTag"] isValidString]){
return 80;
}else if([self isSpecialMessage:messageInfo]){
return 80;
}else{
return 67;
}
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *CellIdentifier = #"message";
if(self.events == nil){
NSDictionary * d = [WEUtil getMyEventListCache];
self.events = [[NSMutableDictionary alloc] init];
for(NSDictionary * eventSummary in d[#"events"]){
NSString * eventID = eventSummary[#"eventid"];
[self.events setObject:eventSummary forKey:eventID];
}
}
UserMessageTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil){
cell = [[UserMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
if(indexPath.row >= [self.messageArray count]){
TERMINATE_WITH_NIL_CELL;
}
NSDictionary *messageInfo = [self.messageArray objectAtIndex:indexPath.row];
if(![self isSpecialMessage:messageInfo]){
[cell configureCellWithMessageDict:messageInfo];
}else{
[cell configureCellWithNewMessageDict:messageInfo withEvents:self.events];
}
return cell;
}
#pragma mark - Navigation
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSDictionary *msgThreadDict = [self.messageArray objectAtIndex:indexPath.row];
if(![self isSpecialMessage:msgThreadDict]){
[self tableView:tableView didSelectNormalRowAtIndexPath:indexPath];
}else{
NSString * event = msgThreadDict[#"event"];
if([event isValidString]){
if([event isEqualToString:#"no_event_messages"]){
[UIUtil showErrorMessage:#"no event id"];
}else{
[BackendTracking trackingWithAction:#"open_special" withLabel:#"threads_list"];
SpecialTopicListViewController * special = [[SpecialTopicListViewController alloc] init];
special.tracking_src = #"tab";
[self.navigationController pushViewController:special animated:YES];
}
}
}
}
-(void) tableView:(UITableView *)tableView didSelectNormalRowAtIndexPath:(NSIndexPath *)indexPath{
NSDictionary *msgThreadDict = [self.messageArray objectAtIndex:indexPath.row];
NSString *threadID = [msgThreadDict objectForKey:#"threadID"];
NSString *jid = [msgThreadDict objectForKey:#"jid"];
[GATracking trackCategory:#"message" withAction:#"thread_list_item_click" withLabel:threadID];
[[MemChatThreadMessages sharedInstance] setCurrentThreadID:threadID];
PrivateMessageViewController * chatVC = [[PrivateMessageViewController alloc] init];
chatVC.threadID = threadID;
chatVC.targetJID = jid;
chatVC.targetName = [msgThreadDict objectForKey:#"name"];
chatVC.unreadMsgNumber = [[self.messageArray objectAtIndex:indexPath.row][#"unreadCnt"] integerValue];
if ([(NSString *)[msgThreadDict objectForKey:#"isGroup"] isEqualToString:#"1"]) {
chatVC.isGroup = YES;
}else{
chatVC.isGroup = NO;
}
chatVC.src = #"list";
WELogInfo(#"click message");
[self.navigationController pushViewController:chatVC animated:YES];
}
#end
With the update and the changes using those trailing swipe actions there is another View appended before each time I delete an entry (until it doesn't work anymore). I've tried disabling the full trail or implementing iOS 11 trailingSwipeActionsConfigurationForRowAtIndexPath but I can't resolve this issue so far.
Do you see something wrong in the code? The main controller code is in another file.
Try reloading after you delete, after this line
[self.tableView endUpdates];
I think you removed the data from messageArray but as you are not reloading just after that so table view count is still 2 and you are reloading inside the block which might be taking time.
And one more thing you already removing data from messageArray, and then removing from db, So if you fail to remove it from db you are showing its not removed but for user it will be removed, as its no longer in message array

TableView is not updating

I hope you guys help me in my code which is load data from a website. Let's start with the code:
-(void)viewDidLoad
{
[self loadDataFromUrl];
}
-(void)loadDataFromUrl {
NSString *myUrl = [NSString stringWithFormat:#"http://WebSite/PhpFiles/File.php"];
NSURL *blogURL = [NSURL URLWithString:myUrl];
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization
JSONObjectWithData:jsonData options:0 error:&error];
for (NSDictionary *bpDictionary in dataDictionary) {
HotelObject *currenHotel = [[HotelObject alloc]initWithVTheIndex:
[bpDictionary objectForKey:#"TheIndex"] timeLineVideoUserName:
[bpDictionary objectForKey:#"timeLineVideoUserName"] timeLineVideoDetails:
[bpDictionary objectForKey:#"timeLineVideoDetails"] timeLineVideoDate:
[bpDictionary objectForKey:#"timeLineVideoDate"] timeLineVideoTime:
[bpDictionary objectForKey:#"timeLineVideoTime"] timeLineVideoLink:
[bpDictionary objectForKey:#"timeLineVideoLink"] timeLineVideoLikes:
[bpDictionary objectForKey:#"timeLineVideoLikes"] videoImage:
[bpDictionary objectForKey:#"videoImage"] timeDeviceToken:
[bpDictionary objectForKey:#"deviceToken"]];
[self.objectHolderArray addObject:currenHotel];
}
}
-(NSMutableArray *)objectHolderArray{
if(!_objectHolderArray) _objectHolderArray = [[NSMutableArray alloc]init];
return _objectHolderArray;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:
(NSInteger)section
{
return [self.objectHolderArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:
(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
Cell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
HotelObject *currentHotel = [self.objectHolderArray
objectAtIndex:indexPath.row];
cell.lblID.text = currentHotel.vvTheIndex;
cell.lblName.text = currentHotel.vvUserName;
cell.lblCity.text = currentHotel.vvVideoDate;
cell.lblAddress.text = currentHotel.vvVideoLikes;
return cell;
}
The above code is loading data from a Url and fill the TableView and this step working fine. The app has another ViewController which is DetailsView, in DetailsView users can update some info. When the user goes back to the TableView nothing happened (I mean the data still the same and not updated). I have tried to call the loadDataFromurl from ViewDidAppear but it does not work.
I did add:
[self.tableView reloadData];
But still the same result.
Her is also my NSObject code:
-(instancetype)initWithVTheIndex:(NSString *)vTheIndex
timeLineVideoUserName:(NSString *)vUserName
timeLineVideoDetails:(NSString *)vVideoDetails
timeLineVideoDate:(NSString *)vVideoDate
timeLineVideoTime:(NSString *)vVideoTime
timeLineVideoLink:(NSString *)vVideoLink
timeLineVideoLikes:(NSString *)vVideoLikes
videoImage:(NSString *)vVideoImage
timeDeviceToken:(NSString *)vDeviceToken {
self = [super init];
if(self){
self.vvTheIndex = vTheIndex;
self.vvUserName = vUserName;
self.vvVideoDetails = vVideoDetails;
self.vvVideoDate = vVideoDate;
self.vvVideoTime = vVideoTime;
self.vvVideoLink = vVideoLink;
self.vvVideoLikes = vVideoLikes;
self.vvVideoImage = vVideoImage;
self.vvDeviceToken = vDeviceToken;
}
return self;
}
My question is: How can I update the TableView when moving from DetailsView or even when I pull to refresh.
Thanks in advance
You are not properly reloading the data source of your UITableView.
Assuming the remote URL is getting updated with the new data, and the issue is only reloading the TableView, make sure you add your [self.tableView reloadData] AFTER loadDataFromUrl has finished.
The reloadData method will always refresh the table's content, so either it's not being called at the right time or you are not updating self.objectHolderArray. (You can debug that by setting a breakpoint after calling loadDataFromUrl after the update.)
on viewDidLoad lifecycle first [self.tableView reloadData] reload tableview then another work.

UILabel of a TableViewCell changes position on reloadData and onClick

I have a tableView inside my ViewController and every time i try to reloadData or click the cell. A specific label moves higher and stays there.
Before reload or click!:
After reloadData or click a cell:
Any ideas what is going wrong?
I call read function to get all the data in the database and store them in the NSMutableArray siteTableObjectsArray.
dispatch_async(backgroundQueue, ^(void){
[self read:^(BOOL finished) {
if(finished){
dispatch_async(dispatch_get_main_queue(), ^{
siteTableObjectsFinalArray = [siteTableObjectsArray copy];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey:#"work.title" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject: sortDescriptor];
siteTableObjectsFinalArray = [siteTableObjectsFinalArray sortedArrayUsingDescriptors:sortDescriptors];
[self.tableView reloadData];
});
}
}];
});
I copy this array into another NSArray, ( i use two arrays for another reason) and use this array to populate the table as follows:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
WorkCell *cell = (WorkCell *) [tableView dequeueReusableCellWithIdentifier:#"WorkCell"];
SiteTableObject *obj = [siteTableObjectsFinalArray objectAtIndex:indexPath.row];
Authors *currAuth = obj.author;
Works *currentWork = obj.work;
cell.authorLabel.text = currAuth.authorName;
cell.workLabel.text = currentWork.title;
NSString* cleanedString = [obj.text stringByTrimmingCharactersInSet: [NSCharacterSet symbolCharacterSet]];
cell.textLabel.text = cleanedString;
cell.caategoryLabel.text = [categoriesDictionary objectForKey:[NSString stringWithFormat:#"%#",currentWork.categoryID]];
cell.dateLabel.text = [NSString stringWithFormat:#"%#", currentWork.date];
cell.moreLabel.text = [NSString stringWithFormat:#"%i more",obj.more];
return cell;
}
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
cell.backgroundColor = [UIColor clearColor];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
WorkCell *cell = (WorkCell *) [tableView cellForRowAtIndexPath:indexPath];
currentIndexRow =indexPath.row;
SiteTableObject *clickedObject = [siteTableObjectsFinalArray objectAtIndex:indexPath.row];
Works *clickedWork = clickedObject.work;
selectedWorkId = [clickedWork.workID intValue];
if ([cell.moreLabel.text isEqualToString:#"0 more"]) {
[self performSegueWithIdentifier:#"p" sender:self];
}else{
[self performSegueWithIdentifier:#"more" sender:self];
}
}
and then every time I call reloadData it comes to the same result either i have changed the siteTableObjectsFinalArray or not!
After digging in the code i found a notification in WorkCell.h:
"Auto property synthesis will not synthesize property 'textLabel' because it is 'readwrite' but it will be synthesized 'readonly' via another property."
I found out the solution thanks to the notification i noticed!
I just had to add:
#synthesize textLabel in the WorkCell.m file

Using AFNetworking to update a UITableViewCell once a download is complete

Within our app we have a free magazine that users can download in PDF format. If they have not downloaded an issue, that UITableViewCell image has a low alpha so that the user can see that it is not downloaded.
If you tap a cell it will start to download using an AFHTTPRequestOperation and once complete you can view the PDF using QuickLook.
The problem I am having is, when the user initiates the download, then scrolls away and then back, the UITableViewCell that they tapped somehow loses reference that it was downloading and therefore doesn't update the UIProgressView or change the alpha to 1.0 when the download is finished. I cannot for the life of me figure out why [[tableView indexPathForCell:cell] isEqual:indexPath] is not equaling:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
PUCViewpointItem *item = [self.items objectAtIndex:indexPath.row];
// Check to see if we are already on the row that is activated
if (indexPath.row == self.selectedIndexPath.row) {
// File Path
NSString *path = [self itemPath:item];
// Should we read the issue
if (item.isDownloaded && path) {
item.downloadPath = path;
[self readIssue:item];
return;
}
// TableView Cell
PUCViewpointTableViewCell *cell = (PUCViewpointTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
if (!path) {
Utility *utility = [[Utility alloc] init];
NSURLRequest *request = [NSURLRequest requestWithURL:item.url];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
NSString *localPath = [[utility localDirectory] stringByAppendingFormat:#"/%#.pdf", item.name];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:localPath append:NO];
[operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) {
float totalProgress = (float)totalBytesRead/totalBytesExpectedToRead;
if ([[tableView indexPathForCell:cell] isEqual:indexPath]) {
cell.progressView.hidden = NO;
cell.progressView.progress = totalProgress;
item.isDownloading = YES;
item.isDownloaded = NO;
item.progress = totalProgress;
}
}];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([[tableView indexPathForCell:cell] isEqual:indexPath]) {
cell.fullImage.alpha = 1.0f;
cell.progressView.hidden = YES;
item.isDownloaded = YES;
item.isDownloading = NO;
}
NSLog(#"%d == %d", [tableView indexPathForCell:cell].row, indexPath.row);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
if ([[tableView indexPathForCell:cell] isEqual:indexPath]) {
cell.progressView.hidden = YES;
item.isDownloading = NO;
item.isDownloaded = NO;
}
}];
[operation start];
}
return;
}
NSIndexPath *oldIndexPath = self.selectedIndexPath;
self.selectedIndexPath = indexPath;
[tableView beginUpdates];
[tableView endUpdates];
// Which way are we scrolling?
UITableViewScrollPosition position;
if (indexPath.row == 0 || (oldIndexPath && oldIndexPath.row < indexPath.row)) {
position = UITableViewScrollPositionTop;
} else {
position = UITableViewScrollPositionBottom;
}
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:position animated:YES];
}
If I start a download, then scroll down in my tableView, my NSLog statement will log something like 3 == 10 which makes no sense.
Any ideas how I can fix this?
I was curious about your case so I wrote a little test project, you can find it here: https://github.com/mrojas/MRTableViewTest
Basically, the way to solve it was:
Put the logic to download an item, in the item class
Make the cell be the delegate of the item, to be notified about progress/completion
When cells are scrolled (reused), setting the item on them is enough. They figure the current status and set themselves to be delegates.
Check the project, try it, and let me know if you have doubts.
I didn't use AFNetworking but instead simulated some task that takes 10 seconds to complete, in 2 seconds interval.
I think you have to store somewhere (like an NSMutableArray instance variable) the indexPath you are downloading. so you can do something like that :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
if( [indexArray indexOfObject:indexPath] != NSNotFound )
{
// alpha for downloading
}
}
In your AFNetworking completion blocks you should remove this indexPath from you indexArray.
As comments said, cells are not reliable for storing any kind of information as they are reallocated when you scroll
#interface ViewController ()
{
NSMutableArray *_indexArray;
}
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UITableView *table = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
table.delegate = self;
table.dataSource = self;
_indexArray = [#[] mutableCopy];
[self.view addSubview:table];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return 50;
}
// called when you scroll to new cells or when reloadData is called
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"default"];
cell.textLabel.textColor = [UIColor blueColor];
// red color if I'm downloading, else blue
if ([_indexArray indexOfObject:indexPath] != NSNotFound) {
cell.textLabel.textColor = [UIColor redColor];
}
cell.textLabel.text = #"cell in the table";
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
[_indexArray addObject:[indexPath copy]];
NSLog(#"downloading...");
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.textLabel.textColor = [UIColor redColor]; // update UI temporary (until scroll)
// HD Image so I can scroll up and down for testing
NSString *res = #"http://res.cloudinary.com/******/image/upload/*****/Motorola_Razr_HD_Cam_Sample_7_ftzrj0.jpg";
// custom class for download
[[PLSApi api] downloadDataAtURL:[NSURL URLWithString:res] withBlock:^(NSData *data) {
// download complete
[_indexArray removeObject:indexPath];
cell.textLabel.textColor = [UIColor blueColor]; // update UI
NSLog(#"finished...");
}];
}

iOS - Unable to scroll UITableView after remote content loaded

When I load remote content via a block I update the UITableView by calling reloadData. However, I am unable to scroll on this data. I think this is because I have declared that the number of rows in the table is the length of my NSArray variable that will hold the contents of the list. When this is called though, the list has a count of zero. I would have assumed that by calling reloadData on the tableView that it would have recalculated the list size again.
Perhaps I'm missing a step along the way.
Thanks
Here is my code
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: #"MYURL"]];
[self performSelectorOnMainThread:#selector(fetchedData:)
withObject:data waitUntilDone:YES];
});
}
-(void) fetchedData:(NSData *)responseData
{
NSError* error;
id json = [NSJSONSerialization
JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
self.dataList = json;
dispatch_async(dispatch_get_main_queue(), ^(void) {
[self.tableView reloadData];
});
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.dataList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SongCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
if([self.dataList count] > 0){
NSDictionary *chartItem = [self.dataList objectAtIndex:indexPath.row];
NSDictionary *song = [chartItem objectForKey:#"song"];
cell.textLabel.text = [song objectForKey:#"title"];
}
return cell;
}
Check that your json object (and therefore self.dataList) is not nil at the end of the asynchronous call. If it is, then [self.dataList count] will return 0.
Also, make sure that you correctly set self.dataList.dataSource.
This is working now.
The cause of the problem was the I had added a pan gesture to the UITableView
[self.view addGestureRecognizer:self.slidingViewController.panGesture];
This seems to interfere with the ability to scroll on a table. Hopefully this will help anyone who comes across this in the future.

Resources