UiTableview values not getting update upon the array value changed - ios

I am fetching data from a web service which returns an array and I am displaying that array in the table view. I am facing the issue that table values are getting updated but after some time as first it is showing the old value and upon scrolling it shows the new value.
Below is my code.
NSURLRequest *request=[NSMutableURLRequest requestWithURL:url
cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:8.0];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSMutableDictionary *ResultdicNew = [[NSMutableDictionary alloc]initWithDictionary:(NSMutableDictionary *)responseObject];
NSString *message=[ResultdicNew objectForKey:#"status"];
NSString *message1=#"";
if([message isEqualToString:#"success"])
{
NSMutableDictionary *datadic=[ResultdicNew objectForKey:#"data"];
NSMutableDictionary *listDataDic=[datadic objectForKey:#"competitors"];
affArray=[listDataDic valueForKey:#"affiliation"];
countArray=[listDataDic valueForKey:#"total_count"];
_lblEventTitle.text=[datadic valueForKey:#"group_name"];
NSLog(#"affArray here is %#",affArray);
NSLog(#"countArray.count here is %ld",countArray.count);
[self revealCompetitorsView];
}
else
{
message1=[Resultdic objectForKey:#"data"];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:message1
message:message
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}
[SVProgressHUD dismiss];
// NSLog(#"JSON Here is :%lu",(unsigned long)Resultdic.count);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
[SVProgressHUD dismiss];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Error Retrieving Data"
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[alertView show];
}];
[operation start];
#pragma mark - UITableView Datasource, Delegate Methods
#pragma mark -
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [countArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
static NSString *CellIdentifier = #"menuCellNew";
cell= [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"RAMenuCellNew" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
// [cell SetData:[m_ary objectAtIndex:indexPath.row]];
UILabel *lbl=(UILabel*)[cell viewWithTag:420];
UILabel *lbl1=(UILabel*)[cell viewWithTag:421];
lbl.text=[affArray objectAtIndex:indexPath.row];
lbl1.text=[countArray objectAtIndex:indexPath.row];
}
[self.sideTable reloadData];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%ld",(long)indexPath.row);
}

Your problem is in your cellForRowAtIndexPath - you are not updating the cell when you are given an existing cell for reuse.
You need to move the updating of the cell fields outside of the if (cell==nil)... block -
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
static NSString *CellIdentifier = #"menuCellNew";
cell= [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"RAMenuCellNew" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
// [cell SetData:[m_ary objectAtIndex:indexPath.row]];
UILabel *lbl=(UILabel*)[cell viewWithTag:420];
UILabel *lbl1=(UILabel*)[cell viewWithTag:421];
lbl.text=[affArray objectAtIndex:indexPath.row];
lbl1.text=[countArray objectAtIndex:indexPath.row];
return cell;
}
Also, you can register your nib file for your cell in viewDidLoad and then you can use dequeueReusableCellWithIdentifer:forIndexPath which will automatically allocate a new cell if required and you can skip the whole if (cell==nil... bit.
You should also consider creating a UITableViewCell subclass and then you can assign your text fields to IBOutlet properties instead of searching by tag.

Replace this code on cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
static NSString *CellIdentifier = #"menuCellNew";
cell= [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"RAMenuCellNew" owner:self options:nil];
cell = [nib objectAtIndex:0];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.selectionStyle = UITableViewCellSelectionStyleNone;
}
// [cell SetData:[m_ary objectAtIndex:indexPath.row]];
UILabel *lbl=(UILabel*)[cell viewWithTag:420];
UILabel *lbl1=(UILabel*)[cell viewWithTag:421];
lbl.text=[affArray objectAtIndex:indexPath.row];
lbl1.text=[countArray objectAtIndex:indexPath.row];
return cell;
}

Related

Data not showing in table view in JSON parsing in iOS

I am doing JSON parsing, but my data is only shown in log and not in Tableview.
I am showing the main method of JSON parsing below. I would like to show the whole code but Stack Overflow doesn't allow me.
- (void)viewDidLoad
{
[super viewDidLoad];
[_CenterTableview setHidden:NO];
[_CenterTableview reloadData];
NSString *str=#"http://www.vallesoft.com/vlcc_api/getservicenames.php?centrename=";
NSURL * url=[NSURL URLWithString:str];
NSURLRequest *req=[[NSURLRequest alloc]initWithURL:url];
Connection1=[[NSURLConnection alloc]initWithRequest:req delegate:self];
if (Connection1) {
WebData1=[[NSMutableData alloc]init];
}
// [self.CenterTableview reloadData];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSDictionary *json=[NSJSONSerialization JSONObjectWithData:WebData1 options:0 error:0];
NSArray *city_info =[json objectForKey:#"city_info"];
for(NSDictionary *dic in city_info)
{
NSArray *vlcc_service_name=[dic objectForKey:#"vlcc_service_name"];
Centers=[[NSMutableArray alloc]initWithObjects:vlcc_service_name, nil];
//This Nslog showing service name //
NSLog(#"%#",vlcc_service_name);
}
}
But in Tableview, it is not showing:
- (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];
}
cell.textLabel.text = [Centers objectAtIndex:indexPath.row];
return cell;
}
You need to reload the tableview once you get the centers array filled in didFinishLoading
///Your code......
Centers=[[NSMutableArray alloc]initWithObjects:vlcc_service_name, nil];
[_CenterTableview reloadData];
////Your code.....

UItableView deplicated cell when scrolling

Sorry for posting this question again but I've looked into many answers and neither of them was helpfull to solve my issue.
So this my code :
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifier = #"radioCell";
RadioTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[RadioTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
[self configureCommentCell:cell atIndexPath:indexPath];
return cell;
}
when I scroll down my cell get mixed up and some of data are repeated, so I've tried this :
static NSString *CellIdentifier = #"memberCell";
RadioCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[RadioTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
and this :
RadioTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[RadioTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:nil];
}
But it didn't fixed my issue and I get white empty cells ? please how to fix this issue ?
Update
- (void)configureCommentCell:(RadioTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
NSDictionary *object;
if ([_dataArray[indexPath.section] isKindOfClass:[NSArray class]])
object = [_dataArray[indexPath.section] objectAtIndex:indexPath.row];
else
object = [[_dataArray[indexPath.section] valueForKey:#"radioList"] objectAtIndex:indexPath.row];
if (object[#"jsonUrl"]) {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:object[#"jsonUrl"] parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
//NSDictionary *tempObject = (NSDictionary *) responseObject;
if (![[responseObject objectForKey:#"type"] isEqualToString:#"error"]) {
NSDictionary *tempObject = [responseObject[#"data"] objectAtIndex:0];
cell.playingNow.text = tempObject[#"song"];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
}
cell.name.text = [NSString stringWithFormat:#" %#", object[#"title"]];
if (object[#"logoUrl"])
[cell.logo setImageWithURL:[NSURL URLWithString:object[#"logoUrl"]]];
}
I see that your problem is that you are fetching the data of you cells inside configureCommentCell that's called inside cellForRowAtIndexPath. which is wrong, because it too late to fetch data inside cellForRowAtIndexPath, in this delegate method you should return the cell.
this line may be called before retrieving the data from server :
cell.name.text = [NSString stringWithFormat:#" %#", object[#"title"]];
Instead you should:
Fetch the data inside a separate method for example fetchData
when the data is downloaded inside the completion block of AFNetworking method, store the data inside an NSArray called for example myDataArray still inside the completion block call [self.tableView reloadData];
In viewDidLoad method just call your method fetchData
And your cellForRowAtIndexPath should looks like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// hey please give me the cell to display ... harry up please
// please harry up ! oh my god you are fetching data from server
// while I am asking for the cell !
// ok I don't care do what you want
// I will return an empty cell anyway
// and guess what I will not take in consideration
// the retried data because it's inside a block
// which is called asynchronously
static NSString *cellIdentifier = #"radioCell";
RadioTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; if (cell == nil) {
cell = [[RadioTableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier]; }
// now before return the cell you need to update the content of cell
// maybe you have an array of items and you should update the label
// for example here and then return the cell
cell.usernameLabel = self.myDataArray[indexPath.row]; // example
return cell;
}
Well the TableView is reusing the cells, and you add the image every time a cell is displaid. Thus when reusing the cell you add an other image, but there already is an image.
You will have to reuse the image view, and only add the image if you create the cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellIdentifer = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifer];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifer]autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(20,0,30,44)];
imageView.tag = 1001;
[cell addSubview:imageView];
[imageView release], imageView= nil;
}
TabBarTestAppDelegate *delegate = (TabBarTestAppDelegate *)[[UIApplication sharedApplication] delegate];
NSArray *local = delegate.myData;
// ok, it's horrible, don't look at it :-)
cell.textLabel.text = [NSString stringWithFormat:#"%#%#", #" " ,[local objectAtIndex:indexPath.row]];
//
NSString* name = nil;;
if (indexPath.row == 0) {
name = #"topicon";
}
else if (indexPath.row + 1 == [local count]) {
name = #"bottomicon";
}
else {
name = #"innericon";
}
UIImageView *imageView = (UIImageView *)[cell viewWithTag:1001];
imageView.image = [UIImage imageWithContentsOfFile: [[NSBundle mainBundle] pathForResource:name ofType:#"png"]];
return cell;
}

Change CellForRow after didSelectRow AKA calling cellForRowAtIndexPath programmatically

Im currently working on my first "big" project, a currency converter. When i select a row i want every cell to change value of "nan" label to the currency returned from the xmlparse class. But, i don't know how i should call this piece of code from inside the didSelectRow method.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"doingit");
static NSString *simpleTableIdentifier = #"SimpleTableCell";
SimpleTableCell *cell = (SimpleTableCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpleTableCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
// cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
XMLparse *parse = [[XMLparse alloc]init];
[parse setcurrencyname:[Datarray2 objectAtIndex:indexPath.row]];
cell.nameLabel.text = [Datarray2 objectAtIndex:indexPath.row];
cell.prepTimeLabel.text = [NSString stringWithFormat:#"%.9f",[parse convertionrate]];
cell.thumbnailImageView.image = [UIImage imageNamed:[imagearray objectAtIndex:indexPath.row]];
return cell;
}
//didselectrow
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"didSelectRowAtIndexPath");
XMLparse *parse = [[XMLparse alloc]init];
[parse setHowmuchmoney:1];
[parse setValutanamn1:[Datarray objectAtIndex:indexPath.row]];
NSLog(#"%#",[parse valutanamn1]);
[parse loadDataFromXML];
UIAlertView *messageAlert = [[UIAlertView alloc]
initWithTitle:#"Row Selected" message:[Datarray objectAtIndex:indexPath.row] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[messageAlert show];
//call cellForRowAtIndexPath here?
}
You only have to do this:
[self.tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];

NSUserDefault not loading in table view

I have a main view with a button that when pressed it adds the url from the web view(like a bookmark) to a table view. The only problem is that its not loading. ive been at it for hours now but cant figure it out. I think i am loading the data in the table view wrong but not quiet sure.
This is the MainViewController.m
- (IBAction)bookmark:(id)sender {
UIActionSheet *actionSheet =
[[UIActionSheet alloc] initWithTitle:[[[[self webView] request] URL]
absoluteString] delegate:nil cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil otherButtonTitles:#"Add", nil];
[actionSheet showInView:self.view];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSMutableArray *bookmarks = [[[NSUserDefaults standardUserDefaults]
arrayForKey:#"Bookmarks"] mutableCopy];
if (!bookmarks) {
bookmarks = [[NSMutableArray alloc] init];
}
[bookmarks addObject:[[[[self webView]request] URL] absoluteString]];
[[NSUserDefaults standardUserDefaults] setObject:bookmarks
forKey:#"Bookmarks"];
}
}
This is BookmarksViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"%#", bookmarks);
bookmarks = [[[NSUserDefaults standardUserDefaults]
arrayForKey:#"Bookmarks"] mutableCopy];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
[[NSUserDefaults standardUserDefaults] setObject:bookmarks forKey:#"Bookmarks"];
cell.textLabel.text = [self.bookmarks objectAtIndex:indexPath.row];
return cell;
}
When your app is first run there is nothing set for the Bookmarks key in NSUserDefaults. So the line:
bookmarks = [[[NSUserDefaults standardUserDefaults]
arrayForKey:#"Bookmarks"] mutableCopy];
in viewDidLoad leaves bookmarks set to nil.
In your action sheet handler you actually deal with this properly.
And one other big problem is the call to:
[[NSUserDefaults standardUserDefaults] setObject:bookmarks forKey:#"Bookmarks"];
in your cellForRowAtIndexPath... method. Why do you update NSUserDefaults every time a cell is needed? Don't do this.
The command [tableView dequeueReusableCellWithIdentifier:CellIdentifier] does NOT always return a cell. It only returns a cell if there is a cell in the reusable-cell queue.
So your method should be:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[[NSUserDefaults standardUserDefaults] setObject:bookmarks forKey:#"Bookmarks"];
cell.textLabel.text = [self.bookmarks objectAtIndex:indexPath.row];
return cell;
}

Xcode show UIAlertView after UITableRowSelection?

this is my first question, sorry if something is wrong
Well I'm trying to create a view in which i can select a friend from a table view and then it should say the number and the mail on a UIAlertView but I dont know how to do this
the friend list is obtained from an xml file on my site, and then is parsed an showed on a table with a custom cell design
this is the code that creates each cell
- (UITableViewCell *)tableView:(UITableView *)myTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = (UITableViewCell *)[self.messageList dequeueReusableCellWithIdentifier:#"ContactListItem"];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"ContactListItem" owner:self options:nil];
cell = (UITableViewCell *)[nib objectAtIndex:0];
}
NSDictionary *itemAtIndex = (NSDictionary *)[messages objectAtIndex:indexPath.row];
UILabel *userLabel = (UILabel *)[cell viewWithTag:2];
userLabel.text = [itemAtIndex objectForKey:#"user"];
return cell;
}
thanks
Santiago
You have to implement the didSelectRowAtIndexPath: method.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *itemAtIndex = (NSDictionary *)[messages objectAtIndex:indexPath.row];
NSString *name = [itemAtIndex objectForKey:#"user"];
NSString *email = [itemAtIndex objectForKey:#"email"];
NSString *phone = [itemAtIndex objectForKey:#"phone"];
NSString *messageStr = [NSString stringWithFormat:#"Email : %#\nPhone : %#", email, phone];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:name message:messageStr delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alert show];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath is the method you would need to implement. This is assuming the view you are presenting the table view in is the delegate for the table view.
-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Alert view logic happens here getting all the cell information
}

Resources