how to use application delegate method in iphone - iphone

i have try the label value pass one view to another view .i have use the table view and table view put a label . code......
such as
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"%i %i",indexPath.row,indexPath.section];
UITableViewCell *cell =[self.tableViewdequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefaultreuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryNone;
NSMutableArray *arr=[NSMutableArray arrayWithArray:[finalArray objectAtIndex:indexForAll]];
NSLog(#"-=-= arr count %d -=-====",[arr count]);
NSLog(#"%#",[[arr objectAtIndex:indexPath.row]description]);
NSLog(#"-====== row value %d -=======",indexPath.row);
NSLog(#"--=-=--- strike value %#",[[arr objectAtIndex:indexPath.row]valueForKey:#"Strike"]);
//indexForAll=indexPath.row
cell.accessoryType = UITableViewCellAccessoryNone;
cell.highlighted = YES;
NSMutableArray *arr2=[NSMutableArray arrayWithArray:[arr objectAtIndex:indexPath.row]];
NSLog(#" -=-=-=-= Arr2 value : %d ",[arr2 count]);
NSLog(#"%#",[arr2 description]);
//.......................................Strike value.....................................//
UILabel *label1;
label1 =[[UILabel alloc]initWithFrame:CGRectMake(10, 3,50, 15)];
NSLog(#"-=-=--= lable1 value -%#",[[arr2 objectAtIndex:0]valueForKey:#"Strike"]);
[label1 setText:[NSString stringWithFormat:#"%#",
[[arr2 objectAtIndex:0]valueForKey:#"Strike"]]];
label1.textAlignment = UITextAlignmentCenter;
[label1 setFont:[UIFont fontWithName:#"Helvetica" size:12]];
[label1 setTextColor:[UIColor blackColor]];
[cell.contentView addSubview:label1];
NSLog(#"lable1 addded");
[self.tableView reloadData];
i have want to label1 value fetch another view.i have trid but even not success .if any helped
thanks
i have tried
such
AppDelegate_iPhone *appDelegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
but value not pass.

Code for CurrentViewControllerHavingTableView
Hi try making a property of your UILabel and synthesize it in the .m file
#property (nonatomic,retain) UILabel *label1;
#synthesize label1;
Now make an object of your current view in the calling class like this
Code for Calling Class
CurrentViewControllerHavingTableView *viewController = [[CurrentViewControllerHavingTableView alloc] initWithNibName:#"CurrentViewControllerHavingTableView" bundle:[NSBundle mainBundle]];
Make a UILabel *label2;
label2.textlabel.text=viewController.label1.textlabel.text;
This will surely work for you.

Make a Nstring type property in appDeleagate suppose NSString *labelText;
and now
AppDelegate_iPhone *appDelegate = (AppDelegate_iPhone *)[[UIApplication sharedApplication] delegate];
In this class where you set this property.
Now before this line
--->[label1 setText:[NSString stringWithFormat:#"%#", [[arr2 objectAtIndex:0]valueForKey:#"Strike"]]];
set that property of appDelegate.
appDelegate.labelText=[NSString stringWithFormat:#"%#", [[arr2 objectAtIndex:0]valueForKey:#"Strike"]];
And now where you want to use this property make object of appDelegate and access this property by using . operator.
This will definately help you if you implement in correct way.

Related

How to set the subclass of a TableView that was created programmatically? (no storyboards)

I am using a custom framework and I need to set the subclass of my 'TableView' and 'TableViewCell' to the custom framework. I would normally do this easily with the identity inspector but since I created everything programmatically, I do not know how to do it. I am also not using storyboards. Any tips?
---edit----
TableViewController.h
#import <UIKit/UIKit.h>
#import "Tasks.h"
#import "Properties2ViewController.h"
#import "PKRevealController.h"
#import "FMMoveTableView.h"
#import "FMMoveTableViewCell.h"
#import "DetailViewController.h"
#interface ToDoTableViewController : UITableViewController <Properties2ViewControllerDelegate, UITableViewDelegate, FMMoveTableViewDataSource>
#property (strong, nonatomic) NSMutableArray *taskArray;
-(IBAction)addCell:(id)sender;
#end
TableViewController.m
#import "ToDoTableViewController.h"
#implementation ToDoTableViewController
#synthesize taskArray;
- (id)init {
self = [super initWithStyle:UITableViewStyleGrouped];
if (self) {
UINavigationItem *i = [self navigationItem];
[i setTitle:#"Task List"];
[[i title] uppercaseString];
UIBarButtonItem *bbi = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addCell:)];
[[self navigationItem] setRightBarButtonItem:bbi];
[self.tableView setSeparatorColor:[UIColor colorWithRed:26.0/255 green:188.0/255 blue:156.0/255 alpha:1.0f]];
[self.tableView setBackgroundView:nil];
[self.tableView setBackgroundColor:[UIColor colorWithRed:26.0/255 green:188.0/255 blue:156.0/255 alpha:1.0f]];
}
return self;
}
- (id) initWithStyle:(UITableViewStyle)style{
return [self init];
}
-(void) viewDidLoad{
FMMoveTableView *mtc = [[FMMoveTableView alloc]init];
[mtc setDataSource:self];
[self.tableView setDelegate:self];
taskArray = [[NSMutableArray alloc] init];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"UITableViewCell"];
if (!cell)
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:#"UITableViewCell"];
NSString *detailText = [NSString stringWithFormat:#"%.0f", [[taskArray objectAtIndex:[indexPath row]] timeInterval]];
[[cell textLabel] setText:[[taskArray objectAtIndex:[indexPath row]] taskName]];
cell.textLabel.text = [[[taskArray objectAtIndex:[indexPath row]] taskName] uppercaseString];
[[cell textLabel] setFont:[UIFont fontWithName:#"AvenirNext-DemiBold" size:15]];
[cell setBackgroundColor:[UIColor colorWithRed:236.0/255 green:240.0/255 blue:241.0/255 alpha:1.0f]];
cell.textLabel.textColor = [UIColor colorWithRed:26.0/255 green:188.0/255 blue:156.0/255 alpha:1.0f];
[[cell detailTextLabel] setText:detailText];
[[cell detailTextLabel] setFont:[UIFont fontWithName:#"Avenir-Black" size:16]];
return cell;
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [taskArray count];
}
-(IBAction)addCell:(id)sender{
Properties2ViewController *pvc = [[Properties2ViewController alloc]init];
[pvc setDelegate:self];
[self presentViewController:pvc animated:YES completion:NULL];
}
-(void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[[self tableView] reloadData];
}
-(void)properties2ViewControllerDidEnterPropertiesSuccesfully:(Tasks *)t{
if (![[t taskName] isEqual: #""]) {
[taskArray addObject:t];
}
[self.tableView reloadData];
}
-(void)moveTableView:(FMMoveTableView *)tableView moveRowFromIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath{
[tableView moveRowAtIndexPath:fromIndexPath toIndexPath:toIndexPath];
[tableView reloadData];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
Tasks *task = [taskArray objectAtIndex:[indexPath row]];
DetailViewController *dvc = [[DetailViewController alloc]init];
[dvc setTestTask:task];
[[self navigationController] pushViewController:dvc animated:YES];
// PKRevealController *pkrc = [[PKRevealController alloc]initWithFrontViewController:self rightViewController:dvc options:nil];
//[pkrc showViewController:dvc animated:YES completion:NULL];
}
-(void)loadView{
[super loadView];
}
#end
If you are instantiating the UITableView yourself, just instantiate the library class instead. For example, if you said this:
UITableView *tableView = [[UITableView alloc] initWithFrame:frame
style: UITableViewStylePlain];
then do this instead:
LibraryTableView *tableView = [[LibraryTableView alloc] initWithFrame:frame
style:UITableViewStylePlain];
If LibraryTableView provides some other, more specialized initWith… method, you may need to use that instead.
If you're storing a reference to the table view in a property or instance variable, you may also want to change the type of that property or instance variable from UITableView * to LibraryTableView *.
UPDATE
I believe if you're using a UITableViewController, you can create your own table view and assign it to the controller's tableView property:
UITableViewController *tvc = ...;
tvc.tableView = [[LibraryTableView alloc] initWithFrame:frame
style:UITableViewStylePlain];
UPDATE 2
In your viewDidLoad, you're creating an FMMoveTableView, but you're not storing it in the view controller's tableView property. You must store it in the view controller's tableView property, and when you do, the view controller will automatically set the table view's dataSource and delegate to self.
-(void) viewDidLoad{
self.tableView = [[FMMoveTableView alloc] init];
taskArray = [[NSMutableArray alloc] init];
}
In your tableView:cellForRowAtIndexPath:, you need to instantiate an FMMoveTableViewCell, not a UITableViewCell. You send the alloc message to the class you want to instantiate:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell"];
if (!cell) {
cell = [[FMMoveTableViewCell alloc]
initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:#"Cell"];
}
// etc.
If you have your own custom subclass of FMMoveTableViewCell, instantiate that instead.
I have created custom TableViewCells before, you can create a custom class just like you would for viewControllers (File > New > File). When choosing which object to subclass, choose UITableViewCell.
Unfortunately, Xcode will not give you the option to include a .xib file, so you'll have to create one of those too: File > New > File, but this time on the left side of the window that pops up, select 'User Interface' instead of 'Cocoa Touch'. Choose the 'Empty' icon at this screen.
You will be asked whether the device family is iPhone or iPad. Since you are making a table view cell not a viewController, it doesn't matter which you pick.
When you create this object you will be presented with a blank canvas. Drag a 'Table View Cell' from the object library to the canvas and you're set to start creating!
It is of note that where you'd normally create outlets, you should create properties for TableViewCells. This is because other objects are going to be interacting with the TableViewCell, not just the TableViewCell's implementation file.
Here is what a header file for a custom TableViewCell might look like:
#interface MyCustomCell : UITableViewCell
#property (weak, nonatomic) IBOutlet UIImageView *icon;
#property (weak, nonatomic) IBOutlet UILabel *label;
#property (weak, nonatomic) IBOutlet UILabel *number;
#end
My implementation file was empty.
However, that's not all. There is also some work to be done in the TableViewController that will utilize this cell. Be sure to import your TableViewCell's header file.
First, the cell has to be registered in the viewDidLoad method
// Resiter the Nib
UINib *nib = [UINib nibWithNibName:#"MyCustomCell" bundle:nil];
[[self tableView] registerNib:nib forCellReuseIdentifier:#"MyCustomCell"];
And then when the TableViewController determines how to draw the cells:
- (UITableViewCell *) tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:#"MyCustomCell"]
// Then here you can set the properties of each cell
[[cell label] setText:#"Some text here"];
[[cell number] setText:[NSString stringWithFormat:#"%d", 5]];
[[cell icon] setImage:[UIImage imageNamed:#"myImage]];
}
I hope this is helpful!

Update selection from second UITableView in original UITableView

I can't get my first UITableView to update with a setting made in a second UITableView.
A user clicks a row in firstTableView causing secondTableView to be displayed. When the user selects a row, secondTableView disappears and firstTableView is reappears. However, the data isn't updated.
I tried using the following in firstTableView:
- (void) viewWillAppear:(BOOL)animated {
// (verified it's defenitely section 2, row 0 by logging it before and after...)
// (also verified that the source data has been updated before viewWillAppear is called...)
NSIndexPath *durPath = [NSIndexPath indexPathForRow:0 inSection:2];
NSArray *paths = [NSArray arrayWithObject:durPath];
[self.firstTableView reloadRowsAtIndexPaths:paths withRowAnimation:UITableViewRowAnimationNone];
// If I use some row animation, I can clearly see that the correct row is being animated, it's just not being updated.
}
But the label does not update. Obviously I'm missing something.
Both views are modal view controllers.
Here's my cell construction:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [firstTableView dequeueReusableCellWithIdentifier:CellIdentifier];
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(150.0, 15.0, 120.0, 17.0)];
myLabel.backgroundColor = [UIColor clearColor];
myLabel.font = [UIFont systemFontOfSize:14];
myLabel.textAlignment = UITextAlignmentLeft;
static NSString* kConstants[] = {kOption0,kOption1,kOption2,kOption3,kOption4,kOption5,kOption6,kOption7,kOption8,kOption9,kOption10,nil};
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
if (indexPath.section == 2) {
[cell addSubview:myLabel];
}
}
switch (indexPath.section) {
case 0:
// … deal with a bunch of UISwitches
break;
case 1:
// … deal with section 1 stuff
break;
case 2:
{
NSLog(#"Verify that intType has in fact been changed here: %i, %#",intType, kConstants[intType]);
// Even though intType and the constant string reflects the correct (updated) values when returning from secondTableView, myLabel.text does not change, ie: it's correct one line above, but not correct one line below. The myLabel.text is just not updating to the new value.
myLabel.text = kConstants[intType];
cell.textLabel.text = #"Choose Some Value:";
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
}
break;
case 3:
// … deal with section 3 stuff
break;
}
[myLabel release];
return cell;
}
I have finally found the problem: when you reload the cell, (cell == nil) will be false, since the cell is already present.
Also, even if (cell == nil) is true, you are adding a new subview, and not modifying the existing one -- which is not only a memory management problem, it also makes the text unreadable by placing the labels on top of each other.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
static NSString* kConstants[] = {kOption0,kOption1,kOption2,kOption3,kOption4,kOption5,kOption6,kOption7,kOption8,kOption9,kOption10,nil};
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(150.0, 15.0, 120.0, 17.0)];
myLabel.backgroundColor = [UIColor clearColor];
myLabel.font = [UIFont systemFontOfSize:14];
myLabel.textAlignment = UITextAlignmentLeft;
myLabel.tag = 1;
myLabel.text = kConstants[intType];
[cell addSubview:myLabel];
[myLabel release];
cell.textLabel.text = #"Label";
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
} else {
UILabel *myLabel = (UILabel *)[cell viewWithTag:1];
myLabel.text = kConstants[intType];
}
return cell;
}
For anyone who stumbles upon this in the future, I'm posting a complete solution to my question here, thanks especially to Antal for showing me the major error in my table construction.
Using ViewWillAppear to reload the table is a bad idea in general, because it causes the table, or portions of the table to load twice. The proper way to do this is using the Delegate method of the second view controller, which I've done here.
I'm posting the relevant portions of the two view controllers. Both are setup as UViewControllers, not as UITableViewControllers. Both are modal views.
I hope someone finds this useful.
//
// FirstViewController.h
//
#import <UIKit/UIKit.h>
#import "SecondViewController.h"
#interface FirstViewController : UIViewController
<SecondViewControllerDelegate, UITableViewDataSource, UITableViewDelegate>
{
UITableView *firstTableView;
NSArray *myArray;
}
#property (nonatomic, retain) IBOutlet UITableView *firstTableView;
#property (nonatomic, assign) NSArray *myArray;
- (void) didSelectOptions:(NSInteger *)intOptionType;
- (void) didCancelOptions;
#end
//
// FirstViewController.m
//
#import "FirstViewController.h"
#import "Constants.h"
#implementation FirstViewController
#synthesize firstTableView;
#synthesize myArray;
- (void) viewDidLoad {
// Load the array that contains the option names, in this case, constants stored in Constants.h
myArray = [[NSArray alloc] initWithObjects:kStoredRowName0, kStoredRowName1, kStoredRowName2, nil];
}
// do everything else to deal with the first view . . .
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Use the indexPath.section as the identifier since objects in each section share unique construction, ie: switches, etc.
NSString *identifier = [NSString stringWithFormat: #"%d", [indexPath indexAtPosition: 0]];
// In this example I'm storing the important integer value in NSUserDefaults as kStoredConstant
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
UITableViewCell *cell = [firstTableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle: UITableViewCellStyleDefault
reuseIdentifier:identifier]
autorelease];
switch (indexPath.section) {
case 0: // OnOff Controls using UISwitch
NSLog(#"Section 0");
// set up switches …
break;
case 1: // Segmented Controls using UISegmentedControl
NSLog(#"Section 1");
// set up segmented controls …
break;
case 2: // Label that will be selected from SecondViewContoller
NSLog(#"Section 2");
// set up label
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(150.0, 15.0, 120.0, 17.0)];
myLabel.backgroundColor = [UIColor clearColor];
myLabel.font = [UIFont systemFontOfSize:14];
myLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0];
myLabel.textAlignment = UITextAlignmentLeft;
myLabel.tag = indexPath.section;
myLabel.text = [myArray objectAtIndex:[userDefaults integerForKey:kStoredConstant]];
[cell addSubview:myLabel];
[myLabel release];
cell.textLabel.text = #"Choose A Value:";
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
break;
}
} else {
switch (indexPath.section) {
case 0: // OnOff Controls using UISwitch
NSLog(#"Section 0");
break;
case 1: // Segmented Controls using UISegmentedControl
NSLog(#"Section 1");
break;
case 2: // Label that will be selected from SecondViewContoller
{
NSLog(#"Section 2");
UILabel *myLabel = (UILabel *)[cell viewWithTag:indexPath.section];
myLabel.text = [myArray objectAtIndex:[userDefaults integerForKey:kStoredConstant]];
}
break;
}
}
// Format the cell label properties for all cells
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.textLabel.font = [UIFont systemFontOfSize:14];
cell.textLabel.textColor = [UIColor colorWithRed:0.25 green:0.0 blue:0.0 alpha:1.0];
cell.textLabel.highlightedTextColor = [UIColor colorWithRed:1.0 green:1.0 blue:0.9 alpha:1.0];
return cell;
}
- (void) tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
// Un-highlight the selected cell
[firstTableView deselectRowAtIndexPath:indexPath animated:YES];
switch (indexPath.section) {
case 0: // Deal with changes in UISwitch Controls
NSLog(#"Section 0");
break;
case 1: // Deal with changes in Segmented Controls
NSLog(#"Section 1");
break;
case 2: // Launch the SecondViewContoller to select a value
{
SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
secondViewController.secondViewControllerDelegate = self;
[self presentModalViewController:secondViewController animated:YES];
[secondViewController release];
}
break;
}
}
#pragma mark -
#pragma mark SecondViewControllerDelegate
- (void) didSelectOptions:(NSInteger *)intOptionType {
// User selected a row in secondTableView on SecondViewController, store it in NSUserDefaults
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
[userDefaults setInteger:(int)intOptionType forKey:kStoredConstant];
[userDefaults synchronize];
// Reload only the row in firstTableView that has been changed, in this case, row 0 in section 2
[self.firstTableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:[NSIndexPath indexPathForRow:0 inSection:2]]withRowAnimation:UITableViewRowAnimationNone];
[self dismissModalViewControllerAnimated:YES];
}
- (void) didCancelOptions {
// User didn't select a row, instead clicked a done or cancel button on SecondViewController
[self dismissModalViewControllerAnimated:YES];
}
// Make sure and release Array and Table
//
// SecondViewController.h
//
#import <UIKit/UIKit.h>
#protocol SecondViewControllerDelegate <NSObject>
- (void) didCancelOptions;
- (void) didSelectOptions:(NSInteger *)optionType;
#end
#interface SecondViewController : UIViewController
<UITableViewDataSource, UITableViewDelegate>
{
NSArray *myArray;
UITableView *secondTableView;
id secondViewControllerDelegate;
}
#property (nonatomic, retain) NSArray *myArray;
#property (nonatomic, retain) IBOutlet UITableView *secondTableView;
#property (nonatomic, assign) id<SecondViewControllerDelegate> secondViewControllerDelegate;
- (IBAction) doneViewingOptions:(id)sender; // This is wired to a Cancel or a Done Button
#end
//
// SecondViewController.m
//
#import "SecondViewController.h"
#import "Constants.h"
#implementation SecondViewController
#synthesize secondViewControllerDelegate;
#synthesize myArray;
#synthesize secondTableView;
- (void) viewDidLoad {
// Load the array that contains the option names, in this case, constants stored in Constants.h
myArray = [[NSArray alloc] initWithObjects:kStoredRowName0, kStoredRowName1, kStoredRowName2, nil];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Build a default table. This one is simple so the following is the only important part:
cell.textLabel.text = [myArray objectAtIndex:indexPath.row];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Return the changed row value to the FirstViewController using secondViewControllerDelegate
[self.secondViewControllerDelegate didSelectOptions:(NSInteger *)indexPath.row];
}
- (IBAction) doneViewingOptions:(id)sender {
// User didn't select a row, just clicked Done or Cancel button
[self.secondViewControllerDelegate didCancelOptions];
}
// Make sure and release Array and Table
You can use reloadRowsAtIndexPaths to reload a specific row (or rows) and avoid having to reload the entire table.
As for the label that displays the string value, could you post the code so we can see?

Passing an NSArray to a screen and displaying its contents in a table

I am working on a navigation based application for the iPhone. At present, I have an NSArray in the RootViewController.m class, which I want to pass to the SecondViewController.m (the second screen).
The array contains objects that contains an NSString name property which I want to display in each cell, and also contains an NSString address property which I would like to display in small print below the name property, in the same cell. The object also has an NSString distance property which I would like to display on the far right of each cell.
My question is:
How do I pass the NSArray to the SecondViewController, and display the contents of each index of the NSArray as a cell in a table.
How do I customize the appearance of the cell such that it displays the name as the main element, the address property as a sub element, and the distance property, as another sub element?
For this you can create a property "secondArray" in your SecondViewController class synthesize it and release it there and in your FirstViewController class you can initialize that "secondArray" object with contents you want like
//Do something like this in your FirstViewController.m
SecondViewController *secondVC = [[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil]
secondVC.secondArray = firstArray; //firstArray would be your local array in FirstViewController
[self.navigationController pushViewController:secondVC animated:YES];
And then to display the contents in the tableview you will have to create a custom cell with three labels with specific frames that you want in reuseTableViewCellWithIdentifier method.
Then in tableviewCellForRowAtIndexPath method you can initailize the text of the labels by fetching the objects of your "secondArray".
//You can code something like this
-(UITableViewCell *)reuseTableViewCellWithIdentifier:(NSString *)identifier withIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell =[[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier]autorelease];
[cell setFrame:(CGRectMake(0,0,305,50))];
if([identifier isEqualToString:#"CellIdentifier"])
{
//Creating an image view to load the cell image on a table row
UIImageView *imageView1=[[UIImageView alloc]initWithFrame:CGRectMake(8,8,305,50)];
imageView1.tag = IMAGEVIEW1_TAG;
[imageView1 setImage:[UIImage imageWithContentsOfFile:[[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:#"AdjustCell.png"]]];
[cell.contentView addSubview:imageView1];
//Creating a label to wite "name" on the imageView1 of the table cell
UILabel *cellText=[[UILabel alloc]initWithFrame:CGRectMake(6,5,310,20)];
cellText.tag = CELLTEXT_TAG;
cellText.backgroundColor=[UIColor clearColor];
cellText.textColor=[UIColor whiteColor];
cellText.font=[UIFont systemFontOfSize:15.0];
[cell.contentView addSubview:cellText];
[imageView1 addSubview:cellText];
//Creating a label to wite distance on the imageView1 of the table cell
UILabel *distanceText=[[UILabel alloc]initWithFrame:CGRectMake(220,27,100,15)];
distanceText.tag = DISTANCETEXT_TAG;
distanceText.backgroundColor=[UIColor clearColor];
distanceText.textColor=[UIColor whiteColor];
distanceText.font=[UIFont systemFontOfSize:12.0];
[imageView1 addSubview:distanceText];
//Creating a label to wite "value" on the imageView2 of the table cell
UILabel *valueText=[[UILabel alloc]initWithFrame:CGRectMake(4,0,150,15)];
valueText.tag = VALUETEXT_TAG;
valueText.backgroundColor=[UIColor clearColor];
valueText.textColor=[UIColor whiteColor];
valueText.font=[UIFont boldSystemFontOfSize:12.0];
UIImageView *imageView2=[[UIImageView alloc]init];
imageView2.tag = IMAGEVIEW2_TAG;
[imageView2 addSubview:partnerText];
[imageView2 addSubview:valueText];
[imageView1 addSubview:imageView2];
[imageView2 release];
[imageView1 release];
[valueText release];
[distanceText release];
[cellText release];
[partnerText release];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
static NSString *identifier = #"CellIdentifer";
cell = [tblView dequeueReusableCellWithIdentifier:identifier];
if(cell == nil)
cell = [self reuseTableViewCellWithIdentifier:identifier withIndexPath:indexPath];
NSMutableDictionary *Store = [self.secondArray objectAtIndex:indexPath.row]; //fetch your data here
UILabel *cellText = (UILabel *)[cell.contentView viewWithTag:CELLTEXT_TAG];
cellText.text = [Store valueForKey:#"name"]; // initialize you data here
UILabel *distanceText = (UILabel *)[cell.contentView viewWithTag:DISTANCETEXT_TAG];
UILabel *valueText = (UILabel *)[cell.contentView viewWithTag:VALUETEXT_TAG];
valueText.text=[[Store valueForKey:#"value"]uppercaseString];
return cell;
}
for first question my answer is property. You can create the property of array.
for second one, You should use the custom Table View cell. It is the best option. you can create your own design of the cell.
You should make property for Your array in firstView or declare this array and make this a property in appDelegate.then simply make object of the class (for which this property belongs).then by simply using .operator you can access that arry.

iPhone: UITableView not Displaying New Data After Call to reloadData

My problem is that the cell.textLabel does not display the new data following a reload. I can see the cellForRowAtIndexPath being called so I know the reloadData call goes thru. If I log the rowString I see the correct value so the string I set label text to is correct. What am I doing wrong?
I have following code :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
static NSString *RowListCellIdentifier = #"RowListCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:RowListCellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:RowListCellIdentifier]autorelease];
}
NSMutableString *rowString = [[NSMutableString alloc] init];
[rowString appendString:[[[rows objectAtIndex:row] firstNumber]stringValue]];
[rowString appendString:#" : "];
[rowString appendString:[[[rows objectAtIndex:row] secondNumber]stringValue]];
[rowString appendString:#" : "];
[[cell textLabel] setText:rowString];
[rowString release];
return cell;
}
- (void)viewWillAppear:(BOOL)animated {
[self.tableView reloadData];
[super viewWillAppear:animated];
}
try
cell.textLabel.text = $VALUE;
if it doesnt help, are you sure that you have set the tableView.delegate AND the tableView.dataSource?
Try:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.tableView reloadData];
}
What you have now is an unusual construction and might be preventing updates to the UI. In methods that set up a view, you want to call the superclass method before the subclass operations. You reverse the order in methods that tears down a view. You usually don't have to call the viewWillAppear of the super unless you have a custom superclass.
I bet your cell.textLabel is somehow being reset to nil. In my experience I find it easiest to treat the cellForRowAtIndexPath: method as if it's always creating a new cell. Even when it's reusing a cell I want to be ready for everything.
The Header file for cell.textLabel state that the default value is nil. This means that you want to assign a label to the textLabel before you go about changing it's text property.
To do that, replace:
[[cell textLabel] setText:rowString];
with:
UILabel *label = [[UILabel alloc] init];//or initWithFrame:
label.text = rowString;
/* Insert your own customization here */
label.font = [UIFont boldSystemFontOfSize:13.0];
label.backgroundColor = [UIColor clearColor];
label.adjustsFontSizeToFitWidth = YES;
cell.textLabel = label;
[label release];

EXC_BAD_ACCESS on UITableView reloadData call

I've come to the point of pulling my hair out over this one. I keep getting a EXC_BAD_ACCESS when I call the reloadData for the UITableView. I'll lay the groundwork for you here.
MainViewController.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#class iPROSAppDelegate;
#interface MainViewController : UIViewController <UIScrollViewDelegate, UITableViewDelegate, UITableViewDataSource> {
iPROSAppDelegate *parent;
...
NSMutableArray *contentSeqList;
UITableView *contentSeqTable;
}
#property (nonatomic, retain) IBOutlet iPROSAppDelegate *parent;
...
#property (nonatomic, retain) NSMutableArray *contentSeqList;
#property (nonatomic, retain) IBOutlet UITableView *contentSeqTable;
...
- (IBAction)changeMainView:(id)sender;
#end
MainViewController.m
- (IBAction)changeMainView:(id)sender{
//do logs to make sure we get here and grab an NSDictionary object from another class
NSLog(#"got to a change of main view");
NSDictionary *myContentSequences = [[parent csList] grabCSListandReturnJSON:[sender tag]];
NSLog(#"got cs list for tag %#: %#", [sender currentTitle], myContentSequences);
//set up table view
contentSeqTable = [[UITableView alloc] initWithFrame:CGRectMake(40, 20, 240, 300) style:UITableViewStyleGrouped];
contentSeqTable.separatorStyle = UITableViewCellSeparatorStyleSingleLine;
[contentSeqTable setDelegate:self];
[contentSeqTable setDataSource:self];
NSLog(#"delegate: %#, data source: %#", [contentSeqTable delegate], [contentSeqTable dataSource]);
contentSeqList = [[NSMutableArray alloc] init];
//populate nsmutablearray contentseqlist using the nsdictionary mycontentsequences
for (id dashboard in [myContentSequences objectForKey:#"dashboards"]){
if ([dashboard objectForKey:#"error"] == nil){
for (id contentsequence in [dashboard objectForKey:#"contentSequences"]){
[contentSeqList addObject:[contentsequence objectForKey:#"name"]];
NSLog(#"added object to content sequence list: %#", [contentsequence objectForKey:#"name"]);
}
}
}
[contentSeqTable reloadData];
...
}
changeMainView is called when a button is clicked in the main view. Here are the delegate methods also for UITableView. Notice that the NSLogs are the first lines in these methods, but I get neither showing in the console log before the EXC_BAD_ACCESS.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
NSLog(#"content seq list count: %#", [contentSeqList count]);
return [contentSeqList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"setting up the cells");
NSUInteger index = [indexPath indexAtPosition:1];
NSString *myId = #"id";
if (tableView.editing) myId = #"idE";
UILabel *name;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:myId];
if (cell == nil){
cell = [[[UITableViewCell alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 20) reuseIdentifier:myId] autorelease];
float width = 260;
if (tableView.editing) width = 240;
name = [[[UILabel alloc] initWithFrame:CGRectMake(45, 1, width, 53)] autorelease];
[name setBackgroundColor:[UIColor clearColor]];
[name setTextColor:[UIColor blackColor]];
[name setFont:[UIFont fontWithName:#"Helvetica" size: 18]];
[name setAdjustsFontSizeToFitWidth:YES];
[name setMinimumFontSize:11];
[name setNumberOfLines:2];
name.tag = 1;
[cell.contentView addSubview:name];
}
else{
name = (UILabel *)[cell.contentView viewWithTag:1];
}
if ([tableView indexPathForSelectedRow]){
if (indexPath == [tableView indexPathForSelectedRow]){
[name setTextColor:[UIColor whiteColor]];
}
else{
[name setTextColor:[UIColor blackColor]];
}
}
else{
[name setTextColor:[UIColor blackColor]];
}
[name setText:[contentSeqList objectAtIndex:index]];
return cell;
}
The delegate methods are part of the same class, MainViewController. I've also checked that the UITableView was not nil via NSLog right before reloadData. I know I have to be missing something small here. Any suggestions would be much appreciated. Thanks!
Can you show call stack when EXC_BAD_ACCESS occurs?
BTW,
NSUInteger index = [indexPath row];
is much more readable than
NSUInteger index = [indexPath indexAtPosition:1];