UILabel of a TableViewCell changes position on reloadData and onClick - ios

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

Related

tableviewcontroller not working when called from other viewcontroller

I have two tableViewControllers created in storyboard:
categories and stores.
When I select a category, it's supposed to show all stores that are in that category.
(I'm getting stores data from server, but I set a fixed category in the url so it should fetch the same two stores no matter what.)
The weird thing is that when I choose a category, storesController shows up empty,
but if I set it as initial controller, it works.
StoreTableViewController_as_initial.png
StoreTableViewController_from_categories.png
this is how I setup the cells in storeController.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
StoresCell *cell = [tableView dequeueReusableCellWithIdentifier:#"storetile"];
if(cell == nil){
cell = [[StoresCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"storetile"];
}
cell.storelabel.text = [[_results objectAtIndex:[indexPath row]]objectForKey:#"name"];
[cell.storelabel sizeToFit];
cell.subtitleOneLabel.text=[[_results objectAtIndex:[indexPath row]]objectForKey:#"neighborhood"];
cell.subtitleTwoLabel.text = [[_results objectAtIndex:[indexPath row]]objectForKey:#"city"];
NSString *distance = [NSString stringWithFormat:#"~%# km",[[_results objectAtIndex:[indexPath row]]objectForKey:#"distance"]];
cell.distanceLabel.text = distance;
NSString *imgPath = [[_results objectAtIndex:[indexPath row]]objectForKey:#"imgUrl"];
UIImage *thumb = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://andrafterdevelopment.com.br/apps/buscaabc/img/%#",imgPath]]]];
[cell.thumbImage setImage:thumb];
return cell;
}
I break at the return, the method is always called but when it's from categoriesController all labels in my cell are nil.
this is how I call storeController from categoriesController
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath{
NSDictionary *item = [_results objectAtIndex:[indexPath row]];
BOOL hasSub = [[item objectForKey:#"hasSub"] boolValue];
StoreTableViewController *storesTableViewController = [[StoreTableViewController alloc]init];
//storesTableViewController.title = [item valueForKey:#"name"];
//storesTableViewController.category = (int)[item valueForKey:#"id"];
[storesTableViewController.tableView registerClass:[StoresCell class] forCellReuseIdentifier:#"storetile"];
[self.navigationController pushViewController:storesTableViewController animated:YES];
}
I'm guessing this has to do with custom cell or maybe I'm doing it wrong by calling it this way.
If you use Storyboard, you should create your controller via Storyboard.
Set Storyboard ID in Identity inspector for your StoreTableViewController and change your method on:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath{
NSDictionary *item = [_results objectAtIndex:[indexPath row]];
BOOL hasSub = [[item objectForKey:#"hasSub"] boolValue];
StoreTableViewController *storesTableViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"storyboard id"];
storesTableViewController.title = [item valueForKey:#"name"];
storesTableViewController.category = (int)[item valueForKey:#"id"];
[self.navigationController pushViewController:storesTableViewController animated:YES];
}
Or you can use segues and configure your StoreTableViewController in prepareForSegue method:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"StoreTableViewControllerSegureIdentifier"]) {
StoreTableViewController *storesTableViewController = segue.destinationViewController;
storesTableViewController.title = _selectedItem.title;
storesTableViewController.category = _selectedItem.identifier;
}
}
I am guessing you have declared _results as a property in StoreTableViewController right?
If so, change your categoriesController method to:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:
(NSIndexPath *)indexPath{
NSDictionary *item = [_results objectAtIndex:[indexPath row]];
BOOL hasSub = [[item objectForKey:#"hasSub"] boolValue];
StoreTableViewController *storesTableViewController = [[StoreTableViewController alloc]init];
storesTableViewController.title = [item valueForKey:#"name"];
storesTableViewController.category = (int)[item valueForKey:#"id"];
[self.navigationController pushViewController:storesTableViewController animated:YES];
}
And register cell in viewDidLoad.
Their are few things that i think you should check in your code.
When you are opening second view controller for selected category, did your service giving you data?
If you are getting data, then is it getting filled in array in right way?
And if everything above is fine, then had you called [tableView reloadData] method after filling data in array.

Load more UICell in the bottom of the UITableView

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).

Why same nsmutablearray gives me valid value and a null on different functions used

I have a NSMutableArray with some objects of type Notes i.e. my class with attributes, iD,note,noteTitle.. I am using the notes array to populate a tableview, and on click, I am trying to open another controller view, to show that specific table row clicked
My code are :
when controller load:
- (void)viewDidLoad {
[super viewDidLoad];
Notes * myNotes =[[Notes alloc] init];
notes = [myNotes getMyNotes];
[super viewDidLoad];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
NSString *title = [NSString stringWithFormat:#"%#...",((Notes *) [notes objectAtIndex:indexPath.row]).noteTitle ];
// here i am using my notes nsmutablearray from above method to populate tableview list of titles.. and it is populated fine.
cell.textLabel.text = title;
cell.imageView.image=[UIImage imageNamed:#"back.jpg"];
return cell;
}
Now when I click a row, I am trying to just see if, I will be getting title, body and it for that certain note..
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
long selectedRow = indexPath.row;
NSString *title = [NSString stringWithFormat:#"%#...",((Notes *) [notes objectAtIndex:selectedRow]).notes];
NSLog(#"%#",title);
}
But I am getting null this time...
why same code in above function is populating my table view but here not even logging it.
Thank you in advance....
You can try in didSelectRowAtIndexPath method
Notes *note = [[Notes alloc]init];
note = [notes objectAtIndex: indexPath.row];
NSString *title = [NSString stringWithFormat:#"%#...",note.notes];
NSLog(#"%#",title);
Hope it works.

To Click Button Pass Json Data To Other ViewCont``roller Tableview

I am developing an ios app..Click on button to Pass The Json Array To other UiViewController TableView To Show The Data In TableView..In TableView Array Data Pass on NSDictionary and to Use Dictionary Object. Error is [__NSCFDictionary objectAtIndex:]: Unrecognised selector sent to instance 0x7b115560']...Thanks In Advance
// Button Click
BBAuthorDetailViewController *BBAuthorDetail =[[UIStoryboard storyboardWithName:#"Main" bundle:nil]instantiateViewControllerWithIdentifier:#"BBAuthorDetail"];
[BBAuthorDetail setSelectionType:BBSelectionAuthorName];
_serverObj = [[Server alloc]init];
[_params setObject:_adDetailsObj.authorDetail forKey:#"author"];
[_serverObj BBAuthorNameWithParams:_params];
// BBAuthorDetail.data=resultsArray;
//NSIndexPath *indexPath = [BBAuthorDetail.tableview indexPathForSelectedRow];
BBAuthorDetail.data = [resultsArray objectAtIndex:indexPath.row];
NSLog(#"%#",resultsArray);
//[BBAuthorDetail setManagedObjectContext:self.managedObjectContext];
[self.navigationController pushViewController:BBAuthorDetail animated:YES];
UIViewController Table TO Show Data
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _data.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *cellIdentifier = [NSString stringWithFormat:#"Cell-%li", (long)indexPath.row];
BBAdsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
// AdDetails *_adDetailsObj = (AdDetails *)[_data objectAtIndex:indexPath.row];
// NSDictionary *dic = [_data objectAtIndex:indexPath.row];
//AdDetails *_adDetailsObj = [[AdDetails alloc]init];
if (cell == nil) {
cell = [[BBAdsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.row = indexPath.row;
//[cell setDelegate:self];
}
// Error Part
NSDictionary *dic = [_data objectAtIndex:0];
cell.textLabel.text = [dic objectForKey:#"post_author"];
return cell;
}

Selecting Cell in Table IOS

I am trying to create a method that changes the string object "tableColorName" to the cell selected. The tableData NSArray consists of object: "red","blue","green". I want to save the string "tableColorName" to redColor if red is selected, blueColor if blue, greenColor if green. After the cell is selected I want the viewController to go back to the root. I appreciate your help in advance:
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int theRow = indexPath.row;
NSString *tableColorName;
tableColorName = [[NSString alloc] initWithString:([_tableData [theRow] stringValue],#"Color")];
[self.navigationController popToRootViewControllerAnimated:YES];
}
//first of all take one NSArray and
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.colorNames = [[NSArray alloc] initWithObjects:#"Red", #"Green",
#"Blue", #"Indigo", #"Violet", nil];
}
// Implement Table method
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.colorNames count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
self.navigationItem.title=#"Colors";
UIImage *cellImage = [UIImage imageNamed:#"a.png"];
cell.imageView.image = cellImage;
NSString *colorString = [self.colorNames objectAtIndex: [indexPath row]];
cell.textLabel.text = colorString;
NSString *subtitle = [NSString stringWithString: #"All about the color "];
subtitle = [subtitle stringByAppendingFormat:colorString];
cell.detailTextLabel.text = subtitle;
return cell;
}
- (void)tableView: (UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
int idx = indexPath.row;
obj.lbl.text=[#"You select "stringByAppendingString:[colorNames objectAtIndex:idx]];
[self popToViewController animated:YES];
}
Try this ::
NSArray *arr;
NSString *tableColorName; // Use in AppDelegate
- (void)viewDidLoad
{
arr = [[NSArray alloc] initWithObjects:#"Red", #"Green", #"Blue", nil];
}
Table View Methods ::
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
cell.title.text = [NSString stringWithFormat:#"%#", [arr objectAtIndex:indexPath.row]];
return cell;
}
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
app.tableColorName = [NSString StringWithFormat:#"%# Color", [arr objectAtIndex:indexPath.row]];
[self.navigationController popToRootViewControllerAnimated:YES];
}
Then, access by app.tableColorName whenever you want to display.
Thanks.
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
//do whatever with the selected cell.
//go back to the root
}

Resources