Assigning label text shows only format string - objective-c

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"MyCell2";
int size = [wordListV2 count];
NSLog(#"there are %d objects in the array", size);
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
// NSString *str =#"%d", [wordListV2[i] ];
// cell.textLabel.text = str;
cell.textLabel.text = #"%d", [wordListV2 count];//[[wordListV2 objectAtIndex:indexPath.row] word];
NSLog(#"Helloo NS LOOOGG %d", [wordListV2 count]);
return cell;
}
The problem is it writes "NSLog part" for "Helloo NS LOOOGG 673" for 673 times but in cell I can only see %d not 673. If I can solve this problem I ll try "[[wordListV2 objectAtIndex:indexPath.row] word]; instead of the number but It doesnt work when Im trying to put it inside cell." Moreover I tried to put it inside a string first then tried but still not working :(
Ok Guys its working now I have another problem
Okey now it works but Its still not what I really want to do. What might be the problems I got an exception and breakpoint stops in 0x10e909b: movl 8(%edx), %edi
I can receive the count of my Array but I cant reach the objects inside it Here is the code :
Words * word = [wordListV2 objectAtIndex:0];
NSLog(#"Helloo NS LOOOGG %#",word.word);
cell.textLabel.text = word.word;
Exception happens when Im trying to reach the NSMutable Array. Moreover I dont know is there any relation with ot but it gives also this
"; }; layer = >",
"; }; layer = >"
)
2013-08-04 18:23:54.720
Btw Words is my class and word is NSSTring * type. And in the end

You see %d because that is the string you are assigning to the text label, everything after the string literal is ignored (I'm surprised it even compiles):
cell.textLabel.text = #"%d", [wordListV2 count];
What you want to do is to create a new NSString using a method that understands and processes format strings:
cell.textLabel.text = [NSString stringWithFormat:#"%d", [wordListV2 count]];
The reason that the NSLog() works is because it can process format strings. However, ObjC properties do not handle format strings.

Related

Checking/Unchecking a tableviewcell with sections

Previously, I had a large-ish dataset (~530 records) being displayed in a tableview. The data was held in an array of dictionaries with two keys, ID and name. Previously, I tapped a cell, it added a check mark, and it sent the cell row number to a 'selectedArray'. As I had already alphabetically sorted them (still in one section), the indexPath.row which was stored in the selectedArray corresponded to the dictionaries' array index, so I could pull data (the ID) from the record.
I decided that I would split this into headers by alphabetical order (which was an absolute pain, I don't see why it's such a complex process to insert headers into a list of records). But now, as I only used indexPath.row, when I tick the first one, it ticks the first record of each section, and only returns the number 0, so I only get the first record in the whole dataset. Is there a simple way to correct this? Really appreciate any help.
cellForRowAtIndexPath:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"inviteCell"];
// cell.accessoryType = UITableViewCellAccessoryCheckmark;
if ([checkedCells objectForKey:[NSNumber numberWithInt:indexPath.row]] != nil) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
// NSDictionary *friend = [sortedFriendsArray objectAtIndex:indexPath.row];
//---get the letter in the current section---
NSString *alphabet = [nameIndex objectAtIndex:[indexPath section]];
//---get all states beginning with the letter---
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"SELF.name beginswith[c] %#", alphabet];
NSArray *states = [sortedFriendsArray filteredArrayUsingPredicate:predicate];
if ([states count]>0) {
//---extract the relevant state from the states object---
NSDictionary *friend = [states objectAtIndex:indexPath.row];
long long fbid = [[friend objectForKey:#"id"]longLongValue];
NSString *name = [friend objectForKey:#"name"];
NSString *urlString = [NSString stringWithFormat:#"https://graph.facebook.com/%qi/picture?type=square",fbid];
NSURL *url = [NSURL URLWithString:urlString];
UILabel *eventNameLabel = (UILabel *) [cell viewWithTag:1];
eventNameLabel.text = name;
UIImageView *eventLogo = (UIImageView*) [cell viewWithTag:2];
eventLogo.image = [UIImage imageNamed:#"112-group.png"];
// eventLogo.image = [UIImage imageWithData: [NSData dataWithContentsOfURL:url]];;
}
return cell;
}
CURRENT didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSNumber *indexNumber = [NSNumber numberWithInt:indexPath.row];
NSDictionary *friend = [sortedFriendsArray objectAtIndex:indexPath.row];
long long fbid = [[friend objectForKey:#"id"]longLongValue];
NSNumber *fbidNum = [NSNumber numberWithLongLong:fbid];
if ([checkedCells objectForKey:indexNumber] != nil) {
[checkedCells removeObjectForKey:indexNumber];
cell.accessoryType = UITableViewCellAccessoryNone;
}
else
{
[checkedCells setObject:fbidNum forKey:indexNumber];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
NSLog(#"Cell Pressed: %#",indexNumber);
NSLog(#"FBID: %lld",fbid);
NSLog(#"Array: %#",checkedCells);
}
It looks like you're only saving the checked cells by row, not by section and row. At minimum, don't you need to be testing the section as well as the row in this block of code?
if ([checkedCells objectForKey:[NSNumber numberWithInt:indexPath.row]] != nil) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
It's late, and I don't have my Mac handy to try this code, so maybe I'm missing something obvious. I'm not sure what you're talking about only returning zero ... is that indexPath.row?
EDIT:
To account for the section in your data array, I'd suggest storing the data as a dictionary of arrays, one dictionary entry keyed by each letter, with the inner array holding all of the entries starting with that letter. It's a little more complicated to retrieve the data, but it correctly accounts for the section.
I supposed you could create some kind of an offset to account for the number of entries in each section and then use that to index into a flat array, but that would be a lot harder to maintain, in my view. I think the dictionary of arrays is the way to go.

UITableView Load Cell and ObjectForKey

I have a problem that should be quite common. I have an Array of data called taskList this comes from a JSON and has several user data. So far, so good. I make the first objectForKey:#"desc" and returns the result (Description of user) but when I try to add another objectForKey (age for example) it shows only the age :( This is the code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:#"MyCell"];
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"MyCell"] autorelease];
}
NSLog(#"%#",taskList);
cell.textLabel.text = [[taskList objectAtIndex:indexPath.row] objectForKey:#"desc"];
return cell;
cell.textLabel.text = [[taskList objectAtIndex:indexPath.row] objectForKey:#"age"];
return cell;
}
do this instead:
NSString *desc = [[taskList objectAtIndex:indexPath.row] objectForKey:#"desc"];
NSString *age = [[taskList objectAtIndex:indexPath.row] objectForKey:#"age"];
cell.textLabel.text = [desc stringByAppendingString:age];
return cell;
Another example, which formats the string (in this case the only difference is that I'm adding a space between the two but it introduces you to a very very helpful method) (and uses the two strings that we created above):
NSString *textForMyLabel = [NSString stringWithFormat:#"%# %#", desc, age];
cell.textLabel.text = textForMyLabel;
Or to do the same thing without the temporary variable textForMyLabel use:
cell.textLabel.text = [desc stringByAppendingFormat:#" %#", age];
In the code you've posted, you'll never get to the 'age' portion since it will return after setting 'desc'. Even if you fix that, you're still assigning desc and age to the same field in the cell, which isn't likely to be what you want.

NSDictionary to TableView

because i'm a newby at Stackoverflow i cannot comment someones anwser yet. (my reputation is 16..). I got a question about this anwser: How do I put this JSON data into my table view? Please help me, I'm living in a nightmare :)
Fulvio sais you have to use [eventNameList addObject:event]; and [eventNameList objectAtIndex:indexPath.row]; to store and get the event data but. addObject is an NSMutableSet method and objectAtIndex:indexPath.row is not. So i cannot use this method to get the data from the NSMutableSet.
Besides that, i can use the count methods neither.
Any Idea's ?
Assuming you have an NSDictionary, you could use the [dictionary allKeys] method to retrieve an array with all keys (lets call it keyArray for now). For the rowCount you could return the count of objects in this keyArray. To get the item that needs to be displayed in the cell you could use [dictionary objectForKey:[keyArray objectAtIndex:indexPath.row]]] to get the appropriate dictionary for the displayed cell.
In code:
// use the keyArray as a datasource ...
NSArray *keyArray = [jsonDictionary allKeys];
// ------------------------- //
// somewhere else in your code ...
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [keyArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
// set some cell defaults here (mainly design) ...
}
NSString *key = [keyArray objectAtIndex:indexPath.row];
NSDictionary *dictionary = [jsonDictionary objectForKey:key];
// get values from the dictionary and set the values for the displayed cell ...
return cell;
}
#Tieme: apparantly the URL you use already returns an array, you don't really need to process a dictionary (you could just use the array as the dataSource), check out the following:
SBJSON *json = [[[SBJSON alloc] init] autorelease];
NSURL *url = [NSURL URLWithString:#"http://www.my-bjoeks.nl/competitions/fetchRoutes/25.json"];
NSString *string = [[[NSString alloc] initWithContentsOfURL:url] autorelease];
NSError *jsonError = nil;
id object = [json objectWithString:string error:&jsonError];
if (!jsonError) {
NSLog(#"%#", object);
NSLog(#"%#", [object class]); // seems an array is returned, NOT a dictionary ...
}
// if you need a mutableArray for the tableView, you can convert it.
NSMutableArray *dataArray = [NSMutableArray arrayWithArray:object]
eventNameList should be defined as an NSMutableArray, not an NSMutableSet. NSMutableArray responds to both -addObject (it puts the new object at the end of the array) and -objectAtIndex: and when you think about it, a table view is essentially an ordered list and so is an array whereas a set is not.
LUCKY:)
Assuming that you might be having nsmutablearray of nsdictionary.
In such case you can get data using:
[dictionary objectforkey:#"key"] objectAtIndex:indexpath.row]

Read plist data into a NSArray but get null

I got same warning here “local declaration hides instance variable” warning
but I got more problems...
Here is my code
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.someaddress.php"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
// create the connection with the request
// and start loading the data
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
NSLog(#"\n\nCONNECTION: %#", theConnection);
NSData *returnData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil];
NSString *listFile = [[NSString alloc] initWithData:returnData encoding:NSASCIIStringEncoding];
NSMutableArray *plist = [[NSMutableArray alloc] init];
plist = [listFile propertyList];
NSLog( #"\n 1111 plist is \n%#", plist );
//I can get a plist format data here,But nothing in 2222
NSLog(#"Now you see me tableView Row Count");
NSLog(#"TOTAL PLIST ROW COUNT IS = %i", [plist count]);
// Return the number of rows in the section.
return [plist count];
}
and I got Warning here"Local declaration of 'plist' hides instance variable"
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"LightCell";
LightCell0 *cell =(LightCell0 *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[LightCell0 alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell…
NSLog(#"Now you see me Load Data %i", indexPath.row);
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
//I try to get list data here But RETURN NULL
NSLog( #"\n 2222 plist is \n %#", plist);
switch (indexPath.row) {
case 0:
if ([plist valueForKey:#"nodeStatus"] == 0){
cell.lightImageView.image = [UIImage imageNamed:#"lightOff.png"];
NSLog(#"value for key Node Status : %#" ,[self.plists Valuefokey:#"nodeStatus"]);
//also return NULL !!
}
else if([self valueForKey:#"nodeStatus"] == 1){
cell.lightImageView.image = [UIImage imageNamed:#"lightOn.png"];
}
break;
case 1:
cell.lightLocation.text =[plist valueForKey:#"nodeName"] ;
if ([plist valueForKey:#"nodeStatus"] == 0){
cell.lightImageView.image = [UIImage imageNamed:#"lightOff.png"];
}
else if([plist valueForKey:#"nodeStatus"] == 1){
cell.lightImageView.image = [UIImage imageNamed:#"lightOn.png"];
};
break;
default:
break;
}
return cell;
}
This is the tow items I create in a plist
{
category = Light;
nodeID = 1;
nodeName = "Living Room";
nodeStatus = 0;
nodeTrigger = 0;
nodeType = "light_sw";
},
{
category = Light;
nodeID = 2;
nodeName = Kitchen;
nodeStatus = 0;
nodeTrigger = 0;
nodeType = "light_sw";
}
So that's my question ,Why can't I pass "plist" from
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
...
}
to
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
}
and I use NSMutableArray *plist = [[NSMutableArray alloc] init];
But still appear "Local declaration of 'plist' hides instance variable"
???
hope someone can figure out this problem
Best Regards !
and I got Warning here"Local declaration of 'plist' hides instance variable"
Well, then, you should fix that.
The warning is telling you that you've declared two variables named plist: One local to this instance method, and the other an instance variable. The local variable, having a narrower scope, hides the instance variable, so that when you refer to plist in the method, you are referring to the local variable. This means that you cannot access anything stored in the instance variable by another method, nor store anything in it for another method to retrieve.
The solution is either to kill off or to rename the local variable. If the latter is what you want, use Xcode's “Edit All in Scope” feature.
Also:
NSMutableArray *plist = [[NSMutableArray alloc] init];
plist = [listFile propertyList];
Creating the array on the first of those lines is redundant, because you immediately replace your pointer to that array with the pointer to another array, returned by propertyList. Thus, you never use and you leak the first array. You should at least cut out the creation of the first array, and you should probably cut out the entire first line (thereby cutting out both the first array and the local variable).
Here is the code I fix the warning ,the program can build without any warning
it also can display the result after reading the plist in tableview
1.Load the plist:
- (void)viewDidLoad {
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www. someaddress.php"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
NSData *returnData = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:nil error:nil];
NSString *listFile = [[NSString alloc] initWithData:returnData encoding:NSASCIIStringEncoding];
plist = [listFile propertyList];
}
2.return the number to rows
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [plist count];
}
3.read the plist data to show result in cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"LightCell0";
LightCell0 *cell =(LightCell0 *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[LightCell0 alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell…
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
int i;
for (i=0; i<[plist count]; i++) {
//Get nodeName
if(indexPath.row == i)
{
cell.lightLocation.text = [[[plist objectAtIndex:i] valueForKey: #"nodeName"]description];
//Get Light Status to show the image
if ([[[plist objectAtIndex:i] valueForKey: #"nodeStatus"] intValue] == 0){
cell.lightImageView.image = [UIImage imageNamed:#"lightOff.png"];
}
else if([[[plist objectAtIndex:i] valueForKey: #"nodeStatus"] intValue] == 1){
cell.lightImageView.image = [UIImage imageNamed:#"lightOn.png"];
cell.lightSwitch.on=YES;
}
}
}
return cell;
}
It can get the right data ,and display the correct result in the tableview cells
BUTTTTTTT
If you scroll up the tableview,it's ok,when you on the top it will scroll down Automatically
When you "scroll down" the tableview,program crash ???
WHY ??? did I write anything wrong ???
plist = [listFile propertyList];=====>self.plist = [listFile propertyList];
THAT IS CORRECT

UItableView referencing sections from core data:

I am saving some data the user inputs into a data file using SQLITE, I am saving date, time, reading, and a note, as the following:
//Create a Reading Object
Readings *readingObj = [[Readings alloc] initWithPrimaryKey:0];
readingObj.date = date.text;
readingObj.time = time.text;
readingObj.reading = reading.text;
readingObj.note = note.text;
//Add the object //This is where I add the inputs to the SQL data file
[appDelegate addReading:readingObj];
My problem or question is: I want to sort the data in a uitableview with date as the section header and other inputs under the section in a cell. The dates represent the number of sections I would have.
This is what I have for now:
- (NSInteger)numberOfSectionsInTableView:(UITableVie w * )tableView {
return 1;
}
- (NSInteger)tableView:(UITableView * )tableView numberOfRowsInSection:(NSInteger)section {
return [appDelegate.readingsArray count];
}
- (UITableViewCell * )tableView:(UITableView * )tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
HistoryCell *cell = (HistoryCell * )[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[HistoryCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
//Get the object from the array.
Readings *readingObj = [appDelegate.readingsArray objectAtIndex:indexPath.row];
[cell setTodo:readingObj];
return cell;
}
readingsArray is the array where I load all the data to; it has all the data:
NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
Readings *readingObj = [[Readings alloc] initWithPrimaryKey:primaryKey];
readingObj.date = [NSString stringWithUTF8String:(char * )sqlite3_column_text(selectstmt, 1)];
////change to int
readingObj.time = [NSString stringWithUTF8String:(char * )sqlite3_column_text(selectstmt, 2)];
////
readingObj.reading = [NSString stringWithUTF8String:(char * )sqlite3_column_text(selectstmt, 3)];
////
readingObj.note = [NSString stringWithUTF8String:(char * )sqlite3_column_text(selectstmt, 4)];
[appDelegate.readingsArray addObject:readingObj];
[readingObj release];
How can I have multiple sections based on the dates, when I only have one array, which readingsArray that has all the data. couldn't make a dates array because it was confusing for me. The dates sections would have multiple readings during that day.
Any suggestions or thoughts? I can provide more code or explanation about my code if needed.
In the title you mentioned once core data. So you probably have a NSFetchedResultsController in your delegate that fetches all the appropriate objects from core data! Then you should set a NSFetchedResultsController property in your class and set it to the delegates fetchedresultscontroller, so you have can use the fetchedresultscontroller delegate methods very comfortable. Or you just initialize another fetchedresultscontroller. Why do you set the fetchedresultsc. not directly in your tableviewcontroller class?