how to save the state in userdefaults of accessory checkmark-iphone - iphone

I am working on an application having UItableView. In the rows of the table i am able to put checkmarks.Now how to save the state of checkmarks so that even if user close the application
the state should be shaved and in the next launch of application checkmark should be shown.
i have followed the tutorials on NSUSerDefaults but Pulling my hairs where to put the codes of saving and retrieving.I have tried but every time errors are stuffing me and not able to fix.
My Code:
MY.h file
**#protocol LocationSelectionViewControllerDelegate <NSObject>
#required
- (void)rowSelected:(NSString *)selectedValue selectedIndex:(NSInteger)index;
#end**
#interface LocationSelection : UIViewController <UITableViewDelegate,UITableViewDataSource>{
UITableView *table;
***NSInteger selectedIndex;***
NSMutableArray *menuList;
***id <LocationSelectionViewControllerDelegate> delegate;***
}
#property (nonatomic,retain) NSMutableArray *menuList;
#property (nonatomic,retain) IBOutlet UITableView *table;
***#property (nonatomic, assign) id <LocationSelectionViewControllerDelegate> delegate;**
**#property NSInteger selectedIndex;***
#end
my .m file:
#implementation LocationSelection
***#synthesize menuList, table,selectedIndex,delegate;***
- (void)viewDidLoad
{
menuList = [[NSMutableArray alloc] initWithObjects:
[NSArray arrayWithObjects:#"LOCATION1", nil],
[NSArray arrayWithObjects:#"LOCATION2", nil],
[NSArray arrayWithObjects:#"LOCATION3", nil],
nil];
self.title = #"Location Selection";
[table reloadData];
[super viewDidLoad];
}
//MY CELLFORROWATINDEXPATH
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString *CellIdentifier = #"CellIdentifier";
UITableViewCell *cell = [table dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero] autorelease];
}
cell.highlighted = NO;
***NSArray * rowArray = [menuList objectAtIndex:indexPath.row];***
UILabel * nameLabel = [[[UILabel alloc] initWithFrame:CGRectMake(15, 8, 200, 20)] autorelease];
nameLabel.text = [NSString stringWithFormat:#"%#", [rowArray objectAtIndex:0]];
[cell.contentView addSubview:nameLabel];
***cell.accessoryType = (rowArray == selectedIndex && selectedIndex > -1 && selectedIndex < [menuList count]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
return cell;
***
}
//MY DIDSELECTROWATINDEXH
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int newRow = [indexPath row];
if (newRow != selectedIndex)
{
UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
newCell.accessoryType = UITableViewCellAccessoryCheckmark;
if (selectedIndex > - 1 && selectedIndex < [menuList count])
{
NSUInteger newIndex[] = {0, selectedIndex};
NSIndexPath *lastIndexPath = [[NSIndexPath alloc] initWithIndexes:newIndex length:2];
UITableViewCell *oldCell = [tableView cellForRowAtIndexPath: lastIndexPath];
oldCell.accessoryType = UITableViewCellAccessoryNone;
}
selectedIndex = newRow;
NSString *selectedValue=[menuList objectAtIndex:selectedIndex];
[self.delegate rowSelected:selectedValue selectedIndex:selectedIndex];
}
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
}
Use this method to save your data to NSUserDefaults
And set the data in viewDidLoad of LocationSelection

Hi I think it will suit you if you have an object(s) to indicate the checkmark. You can save this to the user defaults through synchronize. In the cellForRowATIndexPath: you can check if the value is present in the user defaults and if yes make the cell accessory as checkmarked and if its not present make it none.

Put a state in your menuList which reflects selection of the cell so even multiselection can be done easily. You can use a dictionary instead of the arrays. Arrays are fine but not as readable, so you have to remember which field contains what and map it to an index.
When the view loads load the menuList array from your userDefaults, when the app closes save the defaults.
In didSelectRowAtIndexPath you save selection in menuList.
In cellForRowAtIndexPath you read menuList and the new array index/dictionary key and set the checkmark.

Related

SubClass UIButton To retain Check Selected Using Custom TableCell in iphone

I have a TableView and I am Using Custom TableCell.In TableCell I have a button. Now in TableView I have created a Bool Value to check whether the Check button is Selected or not.
The problem is When I scroll the Table the cell get reused so the button gets Automatically deselected.
if (checkButton.selected==NO) {
NSLog(#"ooo");
checkButton.selected=YES;
checkSelected=YES;
}
else {
NSLog(#"Okkkkk");
checkButton.selected=NO;
checkSelected=NO;
}
I have an idea to Subclass UIButton with a custom Property of BOOl.But I dont know to workout. Can anyone help me out?
You can keep a track of button selected using the array. Just set value 1 at particular index when button is selected. And set it to 0 when it's deselected.
And then while creating the cell you can check in as follows:
if ([[arr_Check objectAtIndex:indexPath.row] isEqualToString:#"0"])
checkButton.selected=NO;
else
checkButton.selected=YES;
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = [NSString stringWithFormat:#"Cell%i%i",indexPath.section,indexPath.row];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
}
else
{
NSArray *cellSubs = cell.contentView.subviews;
for (int i = 0 ; i < [cellSubs count] ; i++)
{
[[cellSubs objectAtIndex:i] removeFromSuperview];
}
}
UICheckBox *checkBox = [[UICheckBox alloc] initWithFrame:CGRectMake(0, 0, 44.0, 44.0)];
checkBox.tag = indexPath.row;
checkBox.titleLabel.tag = indexPath.section;
[checkBox addTarget:self action:#selector(checkBoxPressed:) forControlEvents:UIControlEventTouchUpInside];
for (NSIndexPath *temp in selectedObjects) {
if ([temp isEqual: indexPath]) {
checkBox.selected = TRUE;
}
}
[cell.contentView addSubview:checkBox];
return cell;
}
-(void)checkBoxPressed:(UICheckBox*)sender
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:sender.tag inSection:sender.titleLabel.tag];
if (sender.selected)
[selectedObjects removeObject:indexPath];
else
[selectedObjects addObject:indexPath];
sender.selected = !sender.selected;
NSLog(#"\n\n%#",selectedObjects);
}
Here selectedObjects is a global NSArray and UICheckBox is a subClass of UIButton
#interface CustomButton : UIButton
#property(nonatomic) BOOL isSelected;
// DO NOT FORGET TO SYNTHESIZE MY isSelected
#end
since you are using a custom cell. you can just make a property CustomButton in your custom cell.
#interface YourCustomCell : UITableViewCell
#property(nonatomic, strong) CustomButton *button;
#end
in your cellForRowAtIndexPath method
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
YourCustomCell *cell = (YourCustomCell*)[tableView dequeueReusableCellWithIdentifier:cellType];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:cellType owner:nil options:nil];
cell = (YourCustomCell*)[nib objectAtIndex:0];
}
//you can add a target to your button here
cell.button addTarget:self action:#selector(changeButtonState:).....
if(cell.button.isSelected == YES)
NSLog(#"selected");
else
NSLog(#"not selected");
-(void)changeButtonState:(CustomButton*)button
{
if(button.isSelected) button.isSelected = NO;
else button.isSelected = YES;
[yourTableView reloadData];
}

UITableViewCell getting the default image when i scroll down and up the UITableView

When i checked a cell, the image associated is changed, but when i had scrolled down and up, the cell got its default image this is my code:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSArray *listData =[self->tableContents objectForKey:
[self->sortedKeys objectAtIndex:[indexPath section]]];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier];
}
NSUInteger row = [indexPath row];
cell.textLabel.text = [listData objectAtIndex:row];
UIImageView *unchecked = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"unchecked.png"]];
UIImageView *checked = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"checked.png"]];
BOOL bChecked = NO;//By default, it's unchecked, so NO
/// Assign cell according to `bChecked`
cell.accessoryView = (bChecked ? checked : unchecked);
return cell;
}
EDIT:
I have edited my code to look as above, but i still get the issue, the default image is getting back when i scroll up my table view.
EDIT 2:
#Openside: So according to your approach, my snippet should look like this:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSArray *listData =[self->tableContents objectForKey:
[self->sortedKeys objectAtIndex:[indexPath section]]];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier];
}
NSUInteger row = [indexPath row];
textClass *myText = (textClass*)[listData objectAtIndex:row];
cell.textLabel.text = myText.text;
UIImageView *unchecked = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"unchecked.png"]];
UIImageView *checked = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"checked.png"]];
cell.accessoryView = (myText.isChecked ? checked : unchecked);
return cell;
}
- (void)tableView:(UITableView *)tableView
didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
textClass *myText=[[textClass alloc]init];
myText.isChecked=YES;
}
I got this exception:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFConstantString text]: unrecognized selector sent to instance 0x673bc'
The line indicating the exception issue is this (in cellForRowAtIndexPath delegate method):
cell.textLabel.text = myText.text;
I have added the class textClass although i am not so convinced, i think i can use a property in the holder class of my UITableView.
As Openside said, while scrolling, the cell will come from dequeue. So, we need to assign image according to new state.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell *cell = ...; ///< reuse a created cell.
if(cell == nil) {
cell = ...; ///< create a new cell
}
BOOL bChecked = ...///< Decide the cell checked or not.
/// Assign cell according to `bChecked`
cell.accessoryView = (bChecked ? imgChecked : imgNonChecked);
return cell;
}
Edit:
As for me, I will decide check status by the method indexPathForSelectedRow of tableView. I assume your table view is not multiple selection. It selects only one row at one time.
So, I decide the checked status by following. Because the tableView holds the information about which indexPath is selected.
NSIndexPath *selIndexPath = [tableView indexPathForSelectedRow];
BOOL bChecked = [indexPath isEqual:selIndexPath];
The problem is that the cell will be refreshed (or reused hence the dequeueReusableCellWithIdentifier ) when you scroll it out of view and then back into view. You need to have a flag on your source object to say if it's checked or not and then add an if statement to determine if the checked.png or unchecked.png image is used.
However, looking at your code the source object is just text, it may be worth creating a subclassed NSObject with two properties
text and
checked
Then your cellForRowAtIndexPath code can determine which image to show.
I hope that helps.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier];
}
NSUInteger row = [indexPath row];
textClass *myText = (textClass*)[listData objectAtIndex:row];
cell.textLabel.text = myText.text;
UIImageView *unchecked = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"unchecked.png"]];
UIImageView *checked = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"checked.png"]];
/// Assign cell according to `bChecked`
cell.accessoryView = (myText.isChecked ? checked : unchecked);
return cell;
}
#interface textClass : NSObject {
#private
NSString *_text;
BOOL _isChecked;
}
#property (nonatomic, retain) NSString *text;
#property (nonatomic, assign) BOOL isChecked;
#end
#implementation textClass
#synthesize text = _text;
#synthesize isChecked = _isChecked;
#end
Ok so here I have created a class called textClass it has two properties text and isChecked. When you load your view populate an NSMutableArray (listData) with these objects using the text you were previously using. When your cell gets checked set the isChecked property to YES when the cell gets reused this property has retained its state outside of the delegate method and should render correctly.
Put the complete code in brackets :
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *SimpleTableIdentifier = #"SimpleTableIdentifier";
NSArray *listData =[self->tableContents objectForKey:
[self->sortedKeys objectAtIndex:[indexPath section]]];
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier: SimpleTableIdentifier];
if(cell == nil) {
cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:SimpleTableIdentifier];
NSUInteger row = [indexPath row];
textClass *myText = (textClass*)[listData objectAtIndex:row];
cell.textLabel.text = myText.text;
UIImageView *unchecked = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"unchecked.png"]];
UIImageView *checked = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"checked.png"]];
cell.accessoryView = (myText.isChecked ? checked : unchecked);
}
return cell;
}
This should definitely work.

UITableView not displaying data from array

Code:
In .h:
NSMutableArray *contentArray;
I'm declaring my array.
In .m
- (void)viewDidLoad
{
[super viewDidLoad];
contentArray = [[NSMutableArray alloc] initWithObjects:#"view", #"browse", #"create", nil];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
I'm setting it up in my view did load.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [contentArray count];
}
I'm setting the number of rows to the array count.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
[[cell textLabel] setText:[contentArray objectAtIndex:indexPath.row]];
return cell;
}
Nothing. But if I do "[[cell textLabel] setText:#"Hello World."];" instead, it works fine.
Are you at least getting 3 empty rows in table ? If yes then just change your code
NSString *tempString = [your_array objectAtIndex:indexPath.row];
cell.textLabel.text = tempString;
If you are not even getting empty strings then make property of your array in .h file. Synthesize it in .m (also release it in delloc function) and finally in viewDidLoad right following
NSMutableArray tempContentArray = [[NSMutableArray alloc] arrayWithObjects:#"view", #"browse", #"create", nil];
self.contentArray=tempArray;
and then write following code to get cell title
NSString *tempString = [self.contentArray objectAtIndex:indexPath.row];
cell.textLabel.text = tempString;
Try to initialize your Array in your init method or call reloadDataon your UITableView after you set your Array.
Your code in .m file is fine. Write property .h file synthesize and dealloc your NSMutable array .m file it may be help you.
simply use following line of code
//initlize nsarray with objects.
-(void)viewDidLoad
{
NSArray *practice_ArrayForDisplayingEx=[NSArray alloc]initWithObjects:#"bhupi",#"bhupi",#"bhupi",#"bhupi",nil];
}
//then use in tableview.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
// UIButton *practice_takeTest_button;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier]autorelease];
}
cell.textLabel.text =[practice_ArrayForDisplayingEx objectAtIndex:indexPath.row];
cell.textLabel.font=[UIFont fontWithName:#"Arial" size:15];
return cell;
}
make sure you included UITableViewDelegate & UITableViewDataSourse prtocol in .h file.
hope it will help you..
Make sure that your .h implements the tableview delegate and datasource... should look like this
#interface myClass : UITableViewController <UITableViewDelegate, UITableViewDataSource>
then make this code in your ViewDidLoad method
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];

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?

Custom UITableViewCells with a programmatically created table

When Ever I try to load data from an array into my table using custom cells it only shows the last cell like its overwriting all the cells until I Get to the end of the list. The table was created programmatically and when the cells don't load the blank table scrolls. If however I load the cells then only the last cell shows up and it won't scroll.
I figure I made a typo or something but I can't really see anything that would be of much help. The parser works and the array is fine its just that the cells are acting strange. I wanted to make it so that I had a fixed bar over the table as well but first I needed to get the custom cells to show up in the table and scroll properly
schedule.h
#interface Schedule : UIViewController <UITableViewDelegate, UITableViewDataSource> {
IBOutlet UITableView *newsTable;
UIActivityIndicatorView *activityIndicator;
CGSize cellSize;
NSXMLParser *fileParser;
NSMutableArray * events;
NSMutableArray * announcements;
NSMutableDictionary * item;
NSString *currentElement;
NSMutableString * currentTitle, * currentDate, * currentSummary, * currentId, * curr entTime, *currentContent;
UITableViewCell *appCell;
}
#property(nonatomic, retain)IBOutlet UITableView *newsTable;
#property(nonatomic, retain)IBOutlet UITableViewCell *appCell;
-(void)parseXMLFileAtURL:(NSString *)URL;
#end
schedule.m
- (void)loadView{
UITableView *tableView = [[UITableView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]
style:UITableViewStylePlain];
tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth;
tableView.delegate = self;
tableView.dataSource = self;
tableView.tag = 4;
[tableView reloadData];
self.view = tableView;
[tableView release];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [events count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
[[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
cell = appCell;
self.appCell = nil;
}
// Configure the cell.
UILabel *label;
label = (UILabel *)[cell viewWithTag:1];
int eventIndex = [indexPath indexAtPosition: [indexPath length] - 1];
label.text = [[events objectAtIndex: eventIndex] objectForKey: #"event"];
return cell;
}
- (void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog(#"webpage parsed");
NSLog(#"events array has %d items", [events count]);
newsTable = (UITableView*)[self.view viewWithTag:4];
[newsTable reloadData];
}
I added more code the problem may be somewhere else.
I think your problem is that the cell is being released. When you call self.appCell = nil;, the object will be released and the variable set to nil. Try changing cell = appCell; to cell = [[appCell retain] autorelease]; so that the cell is retained long enough for the table view to retain it again.
Also, you could change int eventIndex = [indexPath indexAtPosition: [indexPath length] - 1]; to int eventIndex = indexPath.row;. The row and section properties were added to NSIndexPath specifically for use in UITableView, and it is guaranteed that the index path passed to cellForRowAtIndexPath: will contain exactly two indices.
try with following code;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *CellIdentifier = #"CellIdentifier";
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // CustomCell is the class for standardCell
if (cell == nil)
{
NSArray *objectList = [[NSBundle mainBundle] loadNibNamed:#"CustomCell" owner:self options:nil];
for (id currentObject in objectList) {
if([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomCell*)currentObject;
break;
}
}
cell.label.text = [[events objectAtIndex: indexPath.row] objectForKey: #"event"];
}
return cell;
}
when you load the xib file with NSBundle, it will return an array of Bundle. Then you have to check it and then use it.
If you tried like;
NSString *memberName; // member variable
NSString *name = memberName;
memberName = nil;
// the member variable "memberName, giving the reference to name;
//So if you set memberName as nil, name also become a nil value.
// You have to use like;
name = [memberName retain];
memberName = nil;
Try to learn more about iPhone development documents.
Click here for Documentation.
Click here for sample code.
I think it will help you.