Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 10-23-2008, 12:03 AM   #1 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 243
noobAppDeveloper is on a distinguished road
Default A table that allows only one cell to be checkmarked.

Hey guys,
Does anyone know how to have a table where you can only put a checkmark on one cell. Like, if I choose one cell, it deselects the other one? Kind of like the ringtones part with the iphone.
noobAppDeveloper is offline   Reply With Quote
Old 10-23-2008, 12:20 AM   #2 (permalink)
Registered Member
 
RickMaddy's Avatar
 
Join Date: Oct 2008
Location: Denver, CO
Posts: 2,121
RickMaddy will become famous soon enough
Default

Keep an instance variable that tracks the currently selected row. Then in the 'didSelectRowAtIndexPath' table delegate method you remove the checkmark from the row that currently has the checkmark, update the instance variable with the new row, and add the checkmark to the newly selected row.
RickMaddy is offline   Reply With Quote
Old 10-23-2008, 12:24 AM   #3 (permalink)
Registered Member
 
Join Date: Oct 2008
Posts: 53
rendezvouscp is on a distinguished road
Default

Basically what you need to do is keep track of the currently selected object in your table. Whenever someone selects a row at any index path, you’ll need to see if it matches your current object (do nothing), or if it’s a different object. If it’s different, you’ll need to get the index of the currently selected object, deselect it, and then check the one that’s touched.

If you run into issues, post again and I’ll share what code I used. I’m pretty sure I was able to find some example code from Apple on how to do this, but I don’t remember what project it was.

[Looks like RickMaddy beat me to the punch.]
rendezvouscp is offline   Reply With Quote
Old 10-23-2008, 12:29 AM   #4 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 243
noobAppDeveloper is on a distinguished road
Default

Quote:
Originally Posted by rendezvouscp View Post
Basically what you need to do is keep track of the currently selected object in your table. Whenever someone selects a row at any index path, you’ll need to see if it matches your current object (do nothing), or if it’s a different object. If it’s different, you’ll need to get the index of the currently selected object, deselect it, and then check the one that’s touched.

If you run into issues, post again and I’ll share what code I used. I’m pretty sure I was able to find some example code from Apple on how to do this, but I don’t remember what project it was.

[Looks like RickMaddy beat me to the punch.]
Thanks for the prompt reply guys. The problem that I have now is finding the cell that has the check mark on it. I don't know how to iterate through my cells and check if cell.accessoryType == UITableViewCellAccessoryCheckMark. I know how to place a check mark but I don't know how to DECHECK the previous one.
noobAppDeveloper is offline   Reply With Quote
Old 10-23-2008, 12:34 AM   #5 (permalink)
Registered Member
 
RickMaddy's Avatar
 
Join Date: Oct 2008
Location: Denver, CO
Posts: 2,121
RickMaddy will become famous soon enough
Default

It's much easier than that. Keep an instance variable of type 'int' representing the last selected row.

Now when the user selects a new row you create a new IndexPath object with old row number from your instance variable and the appropriate section (probably 0). You now use that IndexPath to get the cell from the table. Clear that cell's accessory view.

Now repeat with the IndexPath of the newly selected row and set its accessory view to the checkbox and then update your instance variable with the new row value.
RickMaddy is offline   Reply With Quote
Old 10-23-2008, 12:41 AM   #6 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 243
noobAppDeveloper is on a distinguished road
Default

Quote:
Originally Posted by RickMaddy View Post
It's much easier than that. Keep an instance variable of type 'int' representing the last selected row.

Now when the user selects a new row you create a new IndexPath object with old row number from your instance variable and the appropriate section (probably 0). You now use that IndexPath to get the cell from the table. Clear that cell's accessory view.

Now repeat with the IndexPath of the newly selected row and set its accessory view to the checkbox and then update your instance variable with the new row value.
Ok, thanks I got it to work by creating an indexPath variable. However, what I would like to know is how exactly indexPaths work. I know that you can do indexpath.row or indexpath.section to get what row and section. But how do you go about creating an indexpath from a row num and row section? Btw, your help is really appreciated. thanks
noobAppDeveloper is offline   Reply With Quote
Old 10-23-2008, 12:45 AM   #7 (permalink)
Registered Member
 
RickMaddy's Avatar
 
Join Date: Oct 2008
Location: Denver, CO
Posts: 2,121
RickMaddy will become famous soon enough
Default

Read the docs on NSIndexPath - but look at the right docs. There is the NSIndexPath class and the NSIndexPath(UITableView) category. You want the latter. There is a class level method for creating an index path used for tables - it takes two arguments - row and section.
RickMaddy is offline   Reply With Quote
Old 10-23-2008, 12:56 AM   #8 (permalink)
Registered Member
 
Join Date: Oct 2008
Posts: 53
rendezvouscp is on a distinguished road
Default

Just a note: I took a little bit of a different approach and don’t track the index row of the selected cell. Instead, I keep track of the object (which is a lot more useful in how I’m using this idea) that’s selected and look at the (IIRC) indexOfObject and use that in order to select the row that I want to deselect. I don’t think this would work with multiple sections though.
rendezvouscp is offline   Reply With Quote
Old 10-23-2008, 12:58 AM   #9 (permalink)
Registered Member
 
Join Date: Sep 2008
Posts: 243
noobAppDeveloper is on a distinguished road
Default

Quote:
Originally Posted by RickMaddy View Post
Read the docs on NSIndexPath - but look at the right docs. There is the NSIndexPath class and the NSIndexPath(UITableView) category. You want the latter. There is a class level method for creating an index path used for tables - it takes two arguments - row and section.
Hmm. Is it in the header files? In the documentation the closest I can find is:
- (NSIndexPath *)indexPathForCellUITableViewCell *)cell
noobAppDeveloper is offline   Reply With Quote
Old 10-23-2008, 03:03 AM   #10 (permalink)
pdm
New Member
 
Join Date: Aug 2008
Posts: 56
pdm is on a distinguished road
Default

Hi All,
I found this thread useful.. so, thought I may get solution for my problem..
I was just wondering if there is any way to select multiple rows and once multiple rows are selected do some action.

For example, selecting multiple mails from 'inbox' and deleting in one shot.

To implement this, what we have to use from iPhone SDK?

Your input is very crucial to me..

Please help me in this regard.

Thanks in advance..

-pdm
pdm is offline   Reply With Quote
Old 10-23-2008, 09:49 AM   #11 (permalink)
New Member
 
Join Date: Sep 2008
Posts: 1,431
PhoneyDeveloper is on a distinguished road
Default

You guys all have the wrong idea.

In your data model keep track of the currently selected cell, or in each model object keep track of whether the object is selected or not. Tell the model object that held the old selection to be not selected. Don't try to unselect a row. Instead, reloadData.

The cell you're trying to unselect may not even exist. The idea of iterating through all the cells in the table doesn't match how UITableView works.
PhoneyDeveloper is offline   Reply With Quote
Old 10-23-2008, 05:18 PM   #12 (permalink)
Registered Member
 
RickMaddy's Avatar
 
Join Date: Oct 2008
Location: Denver, CO
Posts: 2,121
RickMaddy will become famous soon enough
Default

Quote:
Originally Posted by noobAppDeveloper View Post
Hmm. Is it in the header files? In the documentation the closest I can find is:
- (NSIndexPath *)indexPathForCellUITableViewCell *)cell
I'm looking at the iPhone docs right in Xcode. If I type in NSIndexPath in the documentation search it shows two entries. A class and a category named NSIndexPath. If I click on the category NSIndexPath I can see the class method for creating a table specific index path.

The method you are quoting is in the UITableView class - wrong place.
RickMaddy is offline   Reply With Quote
Old 01-09-2010, 09:03 AM   #13 (permalink)
Registered Member
 
Join Date: Dec 2009
Posts: 54
Georg is on a distinguished road
Default

Quote:
Originally Posted by rendezvouscp View Post
Basically what you need to do is keep track of the currently selected object in your table. Whenever someone selects a row at any index path, you’ll need to see if it matches your current object (do nothing), or if it’s a different object. If it’s different, you’ll need to get the index of the currently selected object, deselect it, and then check the one that’s touched.

If you run into issues, post again and I’ll share what code I used. I’m pretty sure I was able to find some example code from Apple on how to do this, but I don’t remember what project it was.

[Looks like RickMaddy beat me to the punch.]
hi, I have just found this thread which is what I am looking for, I have the same problem like noobAppDeveloper encountered. I have been searching for any helpful solution for several days, finally I saw a light in the tunnel. But I still don't know how to get the previous accessoryType to decheckmark old row and checkmark new row, please could you post some code here ? bunch thanks!
Georg is offline   Reply With Quote
Old 01-09-2010, 09:29 AM   #14 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

http://www.iphonedevsdk.com/forum/ip...mark-time.html
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-09-2010, 07:33 PM   #15 (permalink)
Registered Member
 
Join Date: Dec 2009
Posts: 54
Georg is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
hi Brian, thanks for your reply, I've seen this many times but what is the function of "setSelection" ? can you post the setSelection code here for reference please?
Georg is offline   Reply With Quote
Old 01-09-2010, 11:23 PM   #16 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

It's a property. Go reread it. Spend less time asking for code, more time understanding what was already written.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-15-2010, 01:15 PM   #17 (permalink)
Registered Member
 
Join Date: Oct 2009
Posts: 169
dbarrett is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post

Took a look @ the suggested thread, seems to make sense, however I have a few questions as I do not know how/where to define "currentModelString".

I want to allow multiple cells to be checked so here's what I've got:
In .h:
Code:
@interface SecondViewTableViewController : UIViewController {
	
	NSMutableArray *array;
	NSMutableArray *selection;
}

@property(nonatomic, retain) NSMutableArray *array;
@property(nonatomic, retain) NSMutableArray *selection;
and in .m:

Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
		//start BrianSlick's code
	if ([self selection] != nil)
	{
		if ([[self selection] localizedCaseInsensitiveCompare:currentModelString] == NSOrderedSame)
		{
			cell.accessoryType = UITableViewCellAccessoryNone;
		} 
		else
		{
			cell.accessoryType = UITableViewCellAccessoryNone;
		}}
	else
	{
		cell.accessoryType = UITableViewCellAccessoryCheckmark;
	} //end BrianSlick's code
	
	if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
	}
    
    cell.textLabel.text = [array objectAtIndex:indexPath.row];
	
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	NSLog(@"didSelectRowAtIndexPath: row=%d", indexPath.row);
	
	static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
		//start BrianSlick's code
	if ([self selection] != nil)
	{
		if ([[self selection] localizedCaseInsensitiveCompare:currentModelString] == NSOrderedSame)
		{
			cell.accessoryType = UITableViewCellAccessoryCheckmark;
			[self setSelection:nil];
		}
		else
		{
			cell.accessoryType = UITableViewCellAccessoryCheckmark;
			[self setSelection:currentModelString];
		}}
	else
	{ 
		cell.accessoryType = UITableViewCellAccessoryNone;
		[self setSelection:currentModelString]; 
	} //end BrianSlick's code

[tableView reloadData];

}
Any help will be greatly appreciated.

Thanks,
dbarrett
dbarrett is offline   Reply With Quote
Old 01-15-2010, 01:18 PM   #18 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

Start with an empty array.

If a row is selected, add that item to the array.

If the current item is in the array, show the checkmark.

If a checked item is selected again, remove it from the array.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-15-2010, 02:10 PM   #19 (permalink)
Registered Member
 
Join Date: Oct 2009
Posts: 169
dbarrett is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
Start with an empty array.

If a row is selected, add that item to the array.

If the current item is in the array, show the checkmark.

If a checked item is selected again, remove it from the array.
First off, thanks for such a quick response!

Secondly, thanks you for clearing up what was actually going on with the comparison. I don't know why I didn't grasp that earlier, but once you pointed out that illuminated that one of the arrays is empty, it clicked. Thanks.

Here's what I have now, but for some reason the checkmark isn't appearing. According to the NSLog, the action is happening, just no checkmark. Also, getting a warning that "'NSMutable Array' may not respond to '-localizedCase...Compare'.

array = <<the populated array>>
selection = <<the empty array>>

in .m

Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
		//start BrianSlicks code
	if ([self selection] != nil)
	{
		if ([[self selection] localizedCaseInsensitiveCompare:array] == NSOrderedSame)
		{
			cell.accessoryType = UITableViewCellAccessoryCheckmark;
			NSLog(@"checkmark");
		}
		else
		{
			cell.accessoryType = UITableViewCellAccessoryNone;
			NSLog(@"no checkmark");
		}}
	else
	{
		cell.accessoryType = UITableViewCellAccessoryNone;
		NSLog(@"no checkmark");
	}
	
	if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
	}//end BrianSlick's code
    cell.textLabel.text = [array objectAtIndex:indexPath.row];
    	
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
	NSLog(@"didSelectRowAtIndexPath: row=%d", indexPath.row);
	
	static NSString *CellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
		//start BrianSlick's code
	if ([self selection] != nil)
	{
		if ([[self selection] localizedCaseInsensitiveCompare:array] == NSOrderedSame)
		{
			cell.accessoryType = UITableViewCellAccessoryNone;
			NSLog(@"no checkmark");
			[self setSelection:nil];
		}
		else
		{
			cell.accessoryType = UITableViewCellAccessoryCheckmark;
			NSLog(@"checkmark");
			[self setSelection:selection];
		}}
	else
	{ 
		cell.accessoryType = UITableViewCellAccessoryCheckmark;
		NSLog(@"checkmark");
		[self setSelection:selection]; 
	}
	
	[tableView reloadData];
		//end BrianSlick's code
}
dbarrett is offline   Reply With Quote
Old 01-15-2010, 02:13 PM   #20 (permalink)
Emphasizing Fundamentals
 
BrianSlick's Avatar
 
Join Date: Jul 2009
Location: NoVA / DC Area
Age: 36
Posts: 7,990
BrianSlick has a spectacular aura about
Default

You are trying to compare a single string to an array. That doesn't work.

You need to do something more along the lines of:
Code:
if ([theArray containsObject:aString])
If necessary, iterate through the array and then do the single string comparison on each item.
__________________
BriTer Ideas LLC - Professional iOS App Development. Available for hire.

SlickShopper 2 | Free NSLog utility | Leave a PayPal donation.

Are you a newbie? Things you should read:
Definitive Guide To Properties | UITableView Series | Guide To Troubleshooting | Model Object Overview

Do you sit at a desk all day? Walk instead! Follow along with my treadmill desk adventures.
BrianSlick is offline   Reply With Quote
Old 01-15-2010, 02:22 PM   #21 (permalink)
Registered Member
 
Join Date: Oct 2009
Posts: 169
dbarrett is on a distinguished road
Default

Quote:
Originally Posted by BrianSlick View Post
You are trying to compare a single string to an array. That doesn't work.

You need to do something more along the lines of:
Code:
if ([theArray containsObject:aString])
If necessary, iterate through the array and then do the single string comparison on each item.
Thanks again for your help, that got rid of the warning but it's still not displaying the checkmark.

I'll keep messing around with it.

Once again, thank you.

dbarrett

BTW, check your paypal acct.
dbarrett is offline   Reply With Quote
Old 10-22-2010, 02:41 AM   #22 (permalink)
Registered Member
 
Join Date: Aug 2010
Posts: 72
AbhishekApple is on a distinguished road
Default

http://developer.apple.com/library/i...007451-CH9-SW6
AbhishekApple is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 355
6 members and 349 guests
bignoggins, Chickenrig, givensur, linkmx, Objective Zero, PlutoPrime
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,657
Threads: 94,118
Posts: 402,894
Top Poster: BrianSlick (7,990)
Welcome to our newest member, jenniead38
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 12:44 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0