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;
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];
Iam using the did select method to select the data .so data in a particular row is selecting and aim getting the check mark also now my problem is when the check mark is on state the data should be printed in console and if its off the data should be removed from the array. my code is as below
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
NSLog(#"array is %#",array);
static NSString *CustomCellID = #"cell";
contactcellTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CustomCellID];
if (cell == nil)
{
cell=[[contactcellTableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CustomCellID];
NSArray *nib=[[NSBundle mainBundle]loadNibNamed:#"contactcellTableViewCell" owner:self options:nil];
cell =[nib objectAtIndex:0];
}
cell.Firstnamelbl.text = [[array objectAtIndex:indexPath.row] objectForKey:#"first_name"];
cell.Lastnamelbl.text=[[array objectAtIndex:indexPath.row]objectForKey:#"last_name"];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[array removeAllObjects];
contactcellTableViewCell *cell = (contactcellTableViewCell *) [tableView cellForRowAtIndexPath:indexPath];
static NSString *CustomCellID = #"cell";
if (cell == nil)
{
cell=[[contactcellTableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CustomCellID];
NSArray *nib=[[NSBundle mainBundle]loadNibNamed:#"contactcellTableViewCell" owner:self options:nil];
cell =[nib objectAtIndex:0];
}
if (cell.m_checkImageView.image == [UIImage imageNamed:#"Selected.png"])
cell.m_checkImageView.image = [UIImage imageNamed:#"Unselected.png"];
else
cell.m_checkImageView.image = [UIImage imageNamed:#"Selected.png"];
}
I had two labels in cell so that when the particular row is selected the data should be print on the console
i got the answer please find below
if (cell.m_checkImageView.image == [UIImage imageNamed:#"Selected.png"])
{
cell.m_checkImageView.image = [UIImage imageNamed:#"Unselected.png"];
}
else
{
cell.m_checkImageView.image = [UIImage imageNamed:#"Selected.png"];
NSLog(#"string is %#",string);
}
}
now we will see the data when row is selected
After all progress i made with your answers, my issue changed. So i am changing my question with clearer way. I have an UITableView which is showing my retrieved data from Parse.com. So i made a NSMutableArray for adding objects to that array when they are retrieved. But my problem is even i add objects to NSMutableArray, my table does not show anything but default screen of UITableView. I thing the issue is UITableView is formed before my NSMutableArray got its objects. Here is my code:
Note: The PropertyClass is the class which has the properties of my objects.
At MyTableViewController.h
#interface MyTableViewController : UITableViewController <CLLocationManagerDelegate> {
PFObject *object;
}
#property (strong, nonatomic) IBOutlet UITableView *MyTableView;
#end
At UITableViewController.m
#interface MyTableViewController ()
#property(strong)NSMutableArray *myNSMutableArray;
#end
#implementation MyTableViewController
#synthesize myNSMutableArray,MyTableView;
-(void) retrievingDataFromParse{
PFQuery *query = [PFQuery queryWithClassName:#"MyObjectsClass"];
[query whereKey:#"ObjectsNumber" lessThanOrEqualTo:10];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(#"Successfully retrieved %d scores.", objects.count);
if (objects.count==0) {
NSString *objectError = #"There no object retrieved from Parse";
PropertiesClass *PC = [[PropertiesClass alloc]initWithPropert1:objectError Propert2:nil Propert3:nil Propert4:nil];
[myNSMutableArray addObject:PC];
}
for (int i = 0; i < objects.count; i++) {
object = [objects objectAtIndex:i];
NSString *Propert1 = [object objectForKey:#"Propert1"];
NSNumber *Propert2 = [object objectForKey:#"Propert2"];
NSNumber *Propert3 = [object objectForKey:#"Propert3"];
NSString *Propert4 = [object objectForKey:#"Propert4"];
PropertiesClass *PC = [[PropertiesClass alloc]initWithPropert1:Propert1 Propert2:Propert2 Propert3:Propert3 Propert4:Propert4];
[myNSMutableArray addObject:PC];
};
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.myNSMutableArray = [NSMutableArray array];
[self retrievingDataFromParse];
[MyTableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [myNSMutableArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PropertiesClass *PC= [myNSMutableArray objectAtIndex:indexPath.row];
cell.textLabel.text=PC.Propert1;
return cell;
}
Looking at your code i see that you never create a UITableViewCell, you should change this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PropertyClass *PC = [myMutableArray objectAtIndex:indexPath.row];
cell.textLabel.text = PC.x;
return cell;
}
with this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (nil == cell){
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
PropertyClass *PC = [myMutableArray objectAtIndex:indexPath.row];
cell.textLabel.text = PC.x;
return cell;
}
the method dequeueReusableCellWithIdentifier:forIndexPath: return a UITableViewCell only if there are unused, but already allocated, cells in your table view. otherwise it returns nil.
Also when you update the mutable array containing all your data you should call [yourTableView reloadData] to force the table view to reload its content.
Your code is quite cryptic. Few suggestions here.
First, rename variables and methods with camelCaseNotation (camel case notation). For example, MyMutableArray should be myMutableArray. RetrievingDataFromParse should be retrievingDataFromParse (and so on). Start upper case letter are for classes.
Second, what does this code mean (I put comment on your code)?
for (int i = 0; i < objects.count; i++) {
// where do you have defined object?
object = [objects objectAtIndex:i];
NSString *x = [object objectForKey:#"x"];
NSNumber *y = [object objectForKey:#"y"];
NSNumber *z = [object objectForKey:#"z"];
NSString *t = [object objectForKey:#"t"];
// is Mekan a subclass of PropertiyClass or what else?
PropertiyClass *Properties = [[Mekan alloc]initWithx:x y:y z:z t:t]
// what's MekanKalibi? Maybe you need to add Properties
[MyMutableArray addObject:MekanKalibi];
}
Edit
If you don't use iOS6 - (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier you should alloc-init cells.
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(!cell) {
// alloc-init a new cell here...
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// or if you don't use ARC
// cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
PropertyClass *PC = [myMutableArray objectAtIndex:indexPath.row];
cell.textLabel.text = PC.x;
return cell;
Edit 2
I don't know how parse works but I suppose it manages async requests. So, at the end of your for loop, just call reload data in the table.
Parse states:
The InBackground methods are asynchronous, so any code after this will run immediately. Any code that depends on the query result should be moved inside the completion block above.
I had the same problem. When you reload the table, you need to move it so it is inside the block. Worked for me.
I'm not 100% sure how the asynchronous parts affect it so. I know that the start of my viewDidload and the end occured then this block, hence the problem.
People should probably up this as this solves the issue.
Cheers.
All you have to do is reload tableView in the block... this will show data.
for (int i = 0; i < objects.count; i++) {
object = [objects objectAtIndex:i];
NSString *Propert1 = [object objectForKey:#"Propert1"];
NSNumber *Propert2 = [object objectForKey:#"Propert2"];
NSNumber *Propert3 = [object objectForKey:#"Propert3"];
NSString *Propert4 = [object objectForKey:#"Propert4"];
PropertiesClass *PC = [[PropertiesClass alloc]initWithPropert1:Propert1 Propert2:Propert2 Propert3:Propert3 Propert4:Propert4];
[myNSMutableArray addObject:PC];
};
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
**[MyTableView reloadData];**
}];
I'm new to programming in Objective C
Here is my Dilemma: I'm pulling in a JSON file from the web and I'm able to display one of the elements (currDate) to my tableView but now I want to display more. From the code below I would I get it to display both currDate and prevDate
The logic needs to be changed here:
for (NSDictionary *diction in arrayOfEntry) {
NSString *currDate = [diction objectForKey:#"Current Date"];
a = currDate;
NSString *prevDate = [diction objectForKey:#"Previous Date"];
b = prevDate;
[array addObject:a];
}
[[self myTableView]reloadData];
I'm not sure if I need to change anything here but I'm attaching it to show how I'm displaying the array to my viewTable:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [array count];
}
-(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];
}
cell.textLabel.text = [array objectAtIndex:indexPath.row];
//cell.textLabel.text = [array objectsAtIndexes:indexPath.row];
return cell;
}
just add another line:
[array addObject:a];
[array addObject:b];
make arrayOfEntry global. in .h file
NSArray *arrayOfEntry;
In numberOfRowsInSection
[arrayOfEntry count]
In tableView: cellForRowAtIndexPath
NSString *currDate = [[arrayOfEntry objectAtIndex:indexPath.row] objectForKey:#"Current Date"]
NSString *prevDate = [[arrayOfEntry objectAtIndex:indexPath.row] objectForKey:#"Previous Date"]
cell.textLabel.text = [NSString stringWithFormat:#"%# %#", currDate, prevDate];
To add multiple elements to an Array in objective c you need to use:
NSMutableArray *newArr = [NSMutableArray new];
Then:
[newArr addObject:dict1];
If you want, you can then set your NSArray you were using to the NSMutuableArray after the addition of objects is complete.
I have the following code set:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"customCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *nibObjs = [[NSBundle mainBundle] loadNibNamed:#"CustomCellView" owner:nil options:nil];
//cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
for(id currentObj in nibObjs)
{
if([currentObj isKindOfClass:[CustomCell class]])
{
cell = (CustomCell *)currentObj;
}
}
}
AssessmentDetail * anAssess = [module.assessmentDetails4 objectAtIndex:indexPath.row];
[[cell labelAssessment] setText:anAssess.assessmentName4];
return cell;
}
In my custom cell there is a UISlider. What I would like to do is use a button to retrieve the value of each UISlider from each row so I can get a total value.
I thought about doing this but I'm not certain on where to go from there:
- (IBAction) calculateTotal:(id)sender {
static NSString *CellIdentifier = #"customCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
Thanks for the help.
Cycle through the subviews of the UITableView:
- (IBAction) calculateTotal:(id)sender {
NSArray *subViews = [myTableView subviews];
float total;
for (int i = 0; i < subViews.count; i++)
{
id obj = [subViews objectAtIndex:i];
if ([obj isKindOfClass:[CustomCell class]])
{
total += [[obj getMySlider] getValue];
}
}
// do something with total
}