i'm using a custom tablecell but i have a problem with parsing JSON in my uilabel i'm using the code below, this works great. To put something in my UILabel i simple do
cell.One.text = #"xx";
/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CustomCellIdentifier = #"CustomCellIdentifier ";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell"
owner:self options:nil];
for (id oneObject in nib) if ([oneObject isKindOfClass:[CustomCell class]])
cell = (CustomCell *)oneObject;
}
return cell;
}
But when i try to parse something i normally do
- (void)fetchedData:(NSData *)responseData {
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray* lastgame = [json objectForKey:#"items"];
NSDictionary* game = [lastgame objectAtIndex:0];
cell.One.text = [NSString stringWithFormat:#"%#",
[strijd objectForKey:#"One"]
];
}
But on this line i'm recieving an error: (Use of undeclared identifier 'cell') does anyone now how to fix thix?
cell.One.text = [NSString stringWithFormat:#"%#",
[strijd objectForKey:#"One"]
];
cell.One.text = [NSString stringWithFormat:#"%#",
[strijd objectForKey:#"One"]
];
your cell isn't declared in this methode, you have to do this in cellForRowAtIndexPath:
after you declare your cell with: CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];
Related
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"myCell"];
if (cell == nil)
{
[tableView registerNib:[UINib nibWithNibName:#"CustomCell" bundle:nil] forCellReuseIdentifier:#"myCell"];
cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:#"myCell"];
}
if (cell.tag == 0)
{
}
str = [jsonData objectAtIndex:cell.tag];
NSDictionary *dict = [jsonData objectAtIndex:indexPath.row];
cell.lblDeliveryTime.text = [dict valueForKey:#"sysord_ExpectedDeliveryTime"];
cell.lblOrderPlacedTime.text = [dict valueForKey:#"sysord_OrderDateTime"];
cell.lblDeliveryPickUP.text = [dict valueForKey:#"sysord_DeliveryType"];
NSDictionary *dict1 = [jsonData objectAtIndex:cell.tag];
orderidString = [dict1 valueForKey:#"sysord_ID"];
DetailViewController *detailVC=[[DetailViewController alloc]initWithNibName:#"DetailViewController" bundle:nil];
return cell;
}
One of the values is not a NSString but NSNumber.
I would advise you to first check the type but if you want to always convert to string, you can use:
cell.lblDeliveryPickUP.text = [NSString stringWithFormat:#"%#", dict[#"sysord_DeliveryType"]];
When you assign an object from dictionary to a text, you need to make sure it's a NSString type.
cell.lblDeliveryTime.text = [[dict objectForKey:#"sysord_ExpectedDeliveryTime"] stringValue];
cell.lblOrderPlacedTime.text = [[dict objectForKey:#"sysord_OrderDateTime"] stringValue];
cell.lblDeliveryPickUP.text = [[dict objectForKey:#"sysord_DeliveryType"] stringValue];
I have two tables (Cell Identifier: Call and Cell Identifier: Cell2). I'm passing two arrays of Objects (one for each table) however when I go to do this in my tableView my 2nd table is bringing up the same data as my first table and not the data from the 2nd array. My arrays are set globally as NSMutableArray in my .h file. This is where I think the problem is within the code:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// NSString *currDate = [[array objectAtIndex:indexPath.row] objectForKey:#"Current Date"]; //added
// NSString *someOtherKey = [[array objectAtIndex:indexPath.row] objectForKey:#"Some other key"]; //added
cell.textLabel.text = [array objectAtIndex:indexPath.row];
label1.text = [arrayDate1 objectAtIndex:indexPath.row];
label2.text = [arrayDate2 objectAtIndex:indexPath.row];
// cell.textLabel.text = [NSString stringWithFormat:#"%# %#", currDate, someOtherKey]; //added
return cell;
//This will Load the second table (myTableView2)
static NSString *CellIdentifier2 = #"Cell2";
UITableViewCell *cell2 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(!cell2)
{
cell2 = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
}
// NSString *currDate = [[array objectAtIndex:indexPath.row] objectForKey:#"Current Date"]; //added
// NSString *someOtherKey = [[array objectAtIndex:indexPath.row] objectForKey:#"Some other key"]; //added
cell2.textLabel.text = [array2 objectAtIndex:indexPath.row];
return cell2;
}
It is indeed a problem in this function:
The code as written, will simply run until it gets to the first return cell; line and never run the code after that, therefore always returning an instance of a Cell cell.
In order to use two tables like this, you need to be able to tell them apart. Usually, you store both of them in a declared property. For the rest of this answer, I'll assume that you are doing that and that they are called table1 and table2.
Change you code to look like this:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([tableView isEqual:self.table1]) {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell)
{
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// NSString *currDate = [[array objectAtIndex:indexPath.row] objectForKey:#"Current Date"]; //added
// NSString *someOtherKey = [[array objectAtIndex:indexPath.row] objectForKey:#"Some other key"]; //added
cell.textLabel.text = [array objectAtIndex:indexPath.row];
label1.text = [arrayDate1 objectAtIndex:indexPath.row];
label2.text = [arrayDate2 objectAtIndex:indexPath.row];
// cell.textLabel.text = [NSString stringWithFormat:#"%# %#", currDate, someOtherKey]; //added
return cell;
} else if ([tableView isEqual:self.table2]) {
//This will Load the second table (myTableView2)
static NSString *CellIdentifier2 = #"Cell2";
UITableViewCell *cell2 = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(!cell2)
{
cell2 = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2];
}
// NSString *currDate = [[array objectAtIndex:indexPath.row] objectForKey:#"Current Date"]; //added
// NSString *someOtherKey = [[array objectAtIndex:indexPath.row] objectForKey:#"Some other key"]; //added
cell2.textLabel.text = [array2 objectAtIndex:indexPath.row];
return cell2;
}
}
// If you reach this point, we don't recognize the table and return `nil`, then the program will crash. Handle this however you want.
return nil;
Really need help. I've looked everywhere but still i cant find an answer. So, when i scroll my UITableView with custom cells in it its recreating cell each time I see it. As the result it lowers my performance significantly.
my method
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"CellWithViewForProduct";
ProductCell *cell = (ProductCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
ProductDataStruct *dataStruct = [self.arrayData objectAtIndex:indexPath.row];
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"productCell" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[ProductCell class]])
{
cell = (ProductCell *)currentObject;
break;
}
}
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.roundingIncrement = [NSNumber numberWithDouble:0.01];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
NSString *price = [formatter stringFromNumber:[NSNumber numberWithFloat:(dataStruct.price.floatValue * [[[NSUserDefaults standardUserDefaults] objectForKey:#"CurrencyCoefficient"] floatValue])]];
NSString *priceString = [NSString stringWithFormat:#"%# %#", price, [[NSUserDefaults standardUserDefaults] objectForKey:#"Currency"]];
cell.productPrice.text = priceString;
cell.productDescription.text = [NSString stringWithFormat:#"%#", dataStruct.descriptionText];
cell.productTitle.text = [NSString stringWithFormat:#"%#", dataStruct.title];
if (dataStruct.hit.integerValue == 1)
{
[cell.productImage.layer addSublayer:[hitView layer]];
}
else
if (dataStruct.hit.integerValue == 2)
[cell.productImage.layer addSublayer:[newsItemView layer]];
if (!dataStruct.image)
{
if (self.tableView.dragging == NO && self.tableView.decelerating == NO && dataStruct.link)
{
[self startIconDownload:dataStruct forIndexPath:indexPath];
}
// if a download is deferred or in progress, return a placeholder image
//cell.productImage.image = [UIImage imageNamed:#"Placeholder.png"];
// if a download is deferred or in progress, return a loading screen
cell.productImage.alpha = 0;
[cell.productImageLoadingIndocator startAnimating];
}
else
{
if (self.didLoad)
{
cell.productImage.alpha = 0;
}
[cell.productImageLoadingIndocator stopAnimating];
cell.productImage.image = dataStruct.image;
[self imageAnimation: cell.productImage];
}
NSLog(#"WAZAAA");
return cell;
}
This entire chunk of code:
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"productCell" owner:nil options:nil];
for(id currentObject in topLevelObjects)
{
if([currentObject isKindOfClass:[ProductCell class]])
{
cell = (ProductCell *)currentObject;
break;
}
}
seems wrong to me. Above it,
ProductCell *cell = (ProductCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
should be sufficient to get you a cell to use.
first create a #property (nonatomic, assign) IBOutlet ProductCell *prodCell; in the .h
Then in the .m you just need this
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"CellWithViewForProduct";
ProductCell *cell = (ProductCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"productCell" owner:self options:nil];
cell = prodCell;
self.prodCell = nil;
NSLog(#"WAZAAA"); //Now it will only be called when a new cell is created.
}
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.roundingIncrement = [NSNumber numberWithDouble:0.01];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
NSString *price = [formatter stringFromNumber:[NSNumber numberWithFloat:(dataStruct.price.floatValue * [[[NSUserDefaults standardUserDefaults] objectForKey:#"CurrencyCoefficient"] floatValue])]];
NSString *priceString = [NSString stringWithFormat:#"%# %#", price, [[NSUserDefaults standardUserDefaults] objectForKey:#"Currency"]];
cell.productPrice.text = priceString;
cell.productDescription.text = [NSString stringWithFormat:#"%#", dataStruct.descriptionText];
cell.productTitle.text = [NSString stringWithFormat:#"%#", dataStruct.title];
if (dataStruct.hit.integerValue == 1)
{
[cell.productImage.layer addSublayer:[hitView layer]];
}
else
if (dataStruct.hit.integerValue == 2)
[cell.productImage.layer addSublayer:[newsItemView layer]];
if (!dataStruct.image)
{
if (self.tableView.dragging == NO && self.tableView.decelerating == NO && dataStruct.link)
{
[self startIconDownload:dataStruct forIndexPath:indexPath];
}
// if a download is deferred or in progress, return a placeholder image
//cell.productImage.image = [UIImage imageNamed:#"Placeholder.png"];
// if a download is deferred or in progress, return a loading screen
cell.productImage.alpha = 0;
[cell.productImageLoadingIndocator startAnimating];
}
else
{
if (self.didLoad)
{
cell.productImage.alpha = 0;
}
[cell.productImageLoadingIndocator stopAnimating];
cell.productImage.image = dataStruct.image;
[self imageAnimation: cell.productImage];
}
NSLog(#"WAZAAA"); //Here doesn't make any sense, the cell is returned for being displayed, this doesn't mean it's being created.
return cell;
}
I have seen several posts on this here at SO but those solutions don't seem to work for me. Perhaps it's because I'm getting the image URL via JSON. All other text fields in JSON are coming through OK, it's just the image that I can't display and get a SIGABRT error.
The code in question is this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"PostCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *post = [posts objectAtIndex:indexPath.row];
NSString *postText = [post objectForKey:#"post_text"];
NSString *postAuthorName = [post objectForKey:#"post_author_name"];
NSString *postPictureUrl = [post objectForKey:#"post_picture"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:postPictureUrl]];
cell.textLabel.text = postText;
cell.detailTextLabel.text = [NSString stringWithFormat:#"by %#", postAuthorName];
cell.imageView.image = [UIImage imageWithData:data];
return cell;
}
My Table Cell is subtitle with no other changes or wiring.
Any idea where I'm messing up?
PS My full code using async request
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"PostCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *post = [posts objectAtIndex:indexPath.row];
NSString *postText = [post objectForKey:#"post_text"];
NSString *postAuthorName = [post objectForKey:#"post_author_name"];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *postpictureUrl = [post objectForKey:#"http://example.com/post/1200"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:postpictureUrl]];
// NSLog(#"%#", data);
dispatch_async(dispatch_get_main_queue(), ^{
// [[cell imageView] setImage:[UIImage imageWithData:data]];
});
});
cell.textLabel.text = postText;
cell.detailTextLabel.text = [NSString stringWithFormat:#"by %#", postAuthorName];
return cell;
}
You can do this like in :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
[NSThread detachNewThreadSelector:#selector(downloadImages:) toTarget:self withObject: [NSMutableDictionary dictionaryWithObjectsAndKeys:imageURL,#"imageURL",[NSIndexPath indexPathWithIndex:indexPath.row],#"indexPath", nil]];
call above function and
- (void) downloadImages:(NSMutableDictionary*)dict{
NSURL *nurl = [NSURL URLWithString:[dict objectForKey:#"imageURL"]];
NSURLRequest *req = [NSURLRequest requestWithURL:nurl];
NSURLResponse * response;
NSData *data = [NSURLConnection sendSynchronousRequest: req returningResponse: &response error: &error];
UITableViewCell *cell = [YOURTABLENAME cellForRowAtIndexPath:(NSIndexPath*)[dict objectForKey:#"indexPath"]];
cell.imageView.image = [UIImage imageWithData:data];
if (error) {...handle the error}
}
A few minor changes and the below works (ie, thumbnail shows to the left of title and subtitle).
- (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];
}
NSDictionary *post = [posts objectAtIndex:indexPath.row];
cell.textLabel.text = [post objectForKey:#"post_text"];
cell.detailTextLabel.text = [post objectForKey:#"post_author_name"];
NSString *postpictureUrl = [post objectForKey:#"picture"];
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:postpictureUrl]];
cell.imageView.image = [UIImage imageWithData:data];
return cell;
}
Note the use of initWithStyle:UITableViewCellStyleSubtitle instead of Default.
The guide here is an important read:
http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html
Finally, note this is synchronous downloading of images which will not work in the real world.
So I'll be posting another question on SO about the best solution for this.
I have a custom cell with identifyer 'tweetCell' I have imported this into my tableviewcontroller.h file. I have linked the class to the prototype cell in storyboard. All the UILabels are wired up to the cell but I cannot get the tableview to display the custom cell. It did work? Then overnight stopped?!! I understand that class files need to start with an upper case letter, I have changed this but to no avail. Can anyone spot my error here? Thanks in advance......
- (void)fetchTweets
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: #"http://search.twitter.com/search.json?q=%23mysearchhashtag"]];
NSError* error;
tweets = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
});
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return tweets.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"tweetCell";
customCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[customCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NSDictionary *tweet = [tweets objectAtIndex:indexPath.row];
NSString *tweetText = [tweet valueForKey:#"text"];
NSArray *tweetComponents = [tweetText componentsSeparatedByString:#":"];
cell.firstDetail.text = [tweetComponents objectAtIndex:0];
cell.secondDetail.text = [tweetComponents objectAtIndex:1];
cell.thirdDetail.text = [tweetComponents objectAtIndex:2];
return cell;
}
Did you write this method - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView? Try like this.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}