How do I popViewControllerAnimated after a delay? - iphone

I have a UITableViewController that is presented with a list of choices. After the user taps one, I'd like to return to the previous view. The return seems too quick with the code I'm using though. I'd like to pause for 0.2 seconds or so to give the user time to see their selection become checked. Here's the code I'm using now:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger oldSelection = [[selectedCriteria objectAtIndex:criteriaSection] integerValue];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Since there's a "none" selection, we don't deselect if the user taps the one that's already selected
if ([indexPath row] != oldSelection + 1) {
NSIndexPath *selectionIndexPath = [NSIndexPath indexPathForRow:oldSelection+1 // Shift down for "None"
inSection:[indexPath section]];
UITableViewCell *checkedCell = [tableView cellForRowAtIndexPath:selectionIndexPath];
[checkedCell setAccessoryType:UITableViewCellAccessoryNone];
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
[selectedCriteria replaceObjectAtIndex:criteriaSection
withObject:[NSNumber numberWithUnsignedInteger:[indexPath row]-1]];
}
[[self navigationController] popViewControllerAnimated:YES];
}
Is there a good way to add a short delay before the view controller is popped?

Hope this help.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger oldSelection = [[selectedCriteria objectAtIndex:criteriaSection] integerValue];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
// Since there's a "none" selection, we don't deselect if the user taps the one that's already selected
if ([indexPath row] != oldSelection + 1) {
NSIndexPath *selectionIndexPath = [NSIndexPath indexPathForRow:oldSelection+1 // Shift down for "None"
inSection:[indexPath section]];
UITableViewCell *checkedCell = [tableView cellForRowAtIndexPath:selectionIndexPath];
[checkedCell setAccessoryType:UITableViewCellAccessoryNone];
[[tableView cellForRowAtIndexPath:indexPath] setAccessoryType:UITableViewCellAccessoryCheckmark];
[selectedCriteria replaceObjectAtIndex:criteriaSection
withObject:[NSNumber numberWithUnsignedInteger:[indexPath row]-1]];
}
[self performSelector:#selector(dismissController) withObject:nil afterDelay:0.2];
}
This give you a 0.2 seconds delay to call the function "dismissController".
The function "dismissController".
- (void) dismissController {
[[self navigationController] popViewControllerAnimated:YES];
}

Have you tried -performSelector:withObject:afterDelay ?

sleep(0.2) worked for me

Related

Uitableview Accessorytype Checkmark Reset Code

I know how to handle with cellaccesory type check mark, here I want a button to Uncheck the entire tablecell which are checkmarked? Here my code, can any one please help me to code
- (void)viewDidAppear:(BOOL)animated
{
UIBarButtonItem *rest = [[UIBarButtonItem alloc]initWithTitle: #"RESET" style: UIBarButtonItemStyleBordered target: self action: #selector(uncheckCells)];
UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[toolbar setItems:[NSArray arrayWithObjects:rest,flexibleSpace,flexibleSpace,home,nil]];
[self.navigationController.view addSubview:toolbar];
[self.tableView reloadData];
}
Here the code for my functions
-(void)uncheckCells//unchecking function
{
[self.tableView reloadData];//HERE WHAT SHOULD I DO
}
-(void)hom
{
[self dismissModalViewControllerAnimated:YES];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = [ar objectAtIndex:indexPath.row];
cell.selectionStyle=UITableViewCellSelectionStyleNone;
if(cell.accessoryType==UITableViewCellAccessoryCheckmark)
{
cell.backgroundColor=UIColorFromRGB(0xd05818);
cell.detailTextLabel.text=#"packed";
cell.detailTextLabel.textColor=[UIColor cyanColor];
}
else
{
cell.backgroundColor=[UIColor whiteColor];
cell.detailTextLabel.text=#"";
}
return cell;
[self.tableView reloadData];
}
(void) deselect
{
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
}
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView reloadData];
[tableView deselectRowAtIndexPath:indexPath animated:NO];
printf("User selected row %d\n", [indexPath row] + 1);
if ([[tableView cellForRowAtIndexPath:indexPath] accessoryType] == UITableViewCellAccessoryCheckmark)
{
[[tableView cellForRowAtIndexPath:indexPath]setAccessoryType:UITableViewCellAccessoryNone];
}
else
[[tableView cellForRowAtIndexPath:indexPath]setAccessoryType:UITableViewCellAccessoryCheckmark];
[self performSelector:#selector(deselect) withObject:nil afterDelay:0.0f];
[tableView reloadData];
}
If you're doing checkmarks on didSelectRowAtIndexPath: method. A reloadData will work for you.
For eg.
Say you have a button with selector uncheckCells
-(void)uncheckCells
{
[self.tableView reloadData];
}
This should work you.
EDIT: add cell.accessoryType = UITableViewCellAccessoryNone; in your if (cell == nil) condition.
Or do this:
-(void)uncheckCells
{
for (int section = 0, sectionCount = self.tableView.numberOfSections; section < sectionCount; ++section) {
for (int row = 0, rowCount = [self.tableView numberOfRowsInSection:section]; row < rowCount; ++row) {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:section]];
cell.accessoryType = UITableViewCellAccessoryNone;
cell.accessoryView = nil;
}
}
}
I hope it will work.
From reading your code, it looks like you are setting the checkmark on the table view itself.
What you should really be doing is storing whether or not a cell has a check mark in your data source, and using this information in the tableView:cellForRowAtIndexPath: method to display a checkmark or not.
And your deselect method should be going through you datasource and unsetting whatever marker you have there that says whether or not your tableview has a check mark.
That way, when you scroll a tableview, or just call [tableView reloadData]; your datastore will be used to decide whether or not to display a checkmark or not.

deselect the previously selected cell in tableview

I have Table View with Multiple sections in it.
I want to allow only one row selected...My tableview's Selection Property is Set to:SingleSelectioin
Now I am doing this to set the checkmark for selected row
if([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark)
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
else
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
Now what I want is that when I select any other cell, the previously selected cell should be set back to unselected.
I have tried with this
lastIndexpath=indexPath;
and then
[tableView deselectRowAtIndexPath:lastIndexpath animated:YES];
but it gives me bad access on lasIndexPath
EXC_BAD_ACCESS (code=1,address= 0xfe000008)
Kindly Help me with this
any New Suggestions are also welcomed
You want to mark your selected cell, then in didSelectRowAtIndexPath you can write code like this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = (UITableViewCell*)[tableView cellForRowAtIndexPath:indexPath];
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
cell = (UITableViewCell*)[tableView cellForRowAtIndexPath:previousSelectedIndexPath];
[cell setAccessoryType: UITableViewCellAccessoryNone];
if(previousSelectedIndexPath!=nil)
{
[previousSelectedIndexPath release];
previousSelectedIndexPath = nil;
}
previousSelectedIndexPath = [indexPath retain];
}
where previousSelectedIndexPath is previously selected index;
Declare NSIndexPath *lastIndexpath in .h of your controller:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if( lastIndexpath){
if([tableView cellForRowAtIndexPath:lastIndexpath].accessoryType == UITableViewCellAccessoryCheckmark)
{
[tableView cellForRowAtIndexPath:lastIndexpath].accessoryType = UITableViewCellAccessoryNone;
}
else
{
[tableView cellForRowAtIndexPath:lastIndexpath].accessoryType = UITableViewCellAccessoryCheckmark;
}}
lastIndexpath=[indexPath retain]
if([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark)
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
else
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
}
//Take a variable of type indexpath in .h
NSIndexPath *myIndexPath
//Now check it in your cellForRowAtIndexPath: delegate method ..
if(indexPath == myIndexPath)
cell.accessoryType = UITableViewCellAccessoryCheckmark;
else
cell.accessoryType = UITableViewCellAccessoryNone;
//and in your didSelect: Delegate method ...
[tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark
myIndexPath = indexPath;
[tableView reloadData];
Hope this will help you.
in delegate method willSelectRowAtIndexPath , get the current selected index path, set accerroryType to none.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSIndexPath *currentSelectedIndexPath = [tableView indexPathForSelectedRow];
[tableView cellForRowAtIndexPath:currentSelectedIndexPath].accessoryType = UITableViewCellAccessoryNone;
if ([indexPath isEqualTo: currentSelectedIndexPath])
{
return nil;
}
return indexPath;
}

Hiding the table view cells with switch ON/OFF in iPhone

This may be a simple question for you experts but I can't figure out the correct solution.
In my app I created a a table view to list a no of items.
In the first row of the cell there a switch (ON/OFF).
So my client need to hide the bottom cells(other than zeroth cell) when switch is OFF and show all the cells when switch is ON.
I created the switch through code.
Can anyone please help me with how to do this?
Thanks in advance.
numberOfRows dataSource method - make it return 1 and reloadTableView
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
/// ....
self.switchView = [[[UISwitch alloc] initWithFrame:CGRectZero]autorelease];
cell.accessoryView = self.switchView;
[self.switchView setOn:NO animated:NO];
[self.switchView addTarget:self action:#selector(switchChanged:) forControlEvents:UIControlEventValueChanged];
//....
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if [self.switchView.on]
return 1;
else
{
// normal code return
}
}
- (void) switchChanged:(id)sender {
[self.tableView reloadData];
}
You could use insertRowsAtIndexPaths, this will not only add, but also do the animation of adding new row
first add target UIControlEventTouchUpInside into UISwitch.
[switch addTarget:self action:#selector(switchChange:) forControlEvents:UIControlEventValueChanged];
-(void) switchChange:(UISwitch*) sender{
isSwitchOn = sender.on; //edited
[myTable beginUpdates];
NSIndexPath *row1 = [NSIndexPath indexPathForRow:1 inSection:0];
NSIndexPath *row2 = [NSIndexPath indexPathForRow:2 inSection:0];
//you may add as many row as you want here.
[myTable insertRowsAtIndexPaths:[NSArray arrayWithObjects:row1,row2,nil] withRowAnimation:UITableViewRowAnimationMiddle];
[myTable endUpdates];
}
and make sure you will add how many rows you will insert in numberOfRowsInSection:
(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (isSwitchOn) return 1;
else
return 3; //how many rows would have after switched on
}
You might want to check [myTable insertSections:withRowAnimation: to insert another section and do the same as above. but remember to state how many section you will add, in numberOfSectionsInTableView:
UPDATE :
implement deleteRowsAtIndexPaths: if switch off.
-(void) switchChange:(UISwitch*) sender{
isSwitchOn = sender.on;
if(isSwitchOn){
[myTable beginUpdates];
NSIndexPath *row1 = [NSIndexPath indexPathForRow:1 inSection:0];
NSIndexPath *row2 = [NSIndexPath indexPathForRow:2 inSection:0];
//you may add as many row as you want here.
[myTable insertRowsAtIndexPaths:[NSArray arrayWithObjects:row1,row2,nil] withRowAnimation:UITableViewRowAnimationMiddle];
[myTable endUpdates];
}
else{
[myTable beginUpdates];
NSIndexPath *row1 = [NSIndexPath indexPathForRow:1 inSection:0];
NSIndexPath *row2 = [NSIndexPath indexPathForRow:2 inSection:0];
//you may add as many row as you want here.
[myTable deleteRowsAtIndexPaths:[NSArray arrayWithObjects:row1,row2,nil] withRowAnimation:UITableViewRowAnimationFade];
[myTable endUpdates];
}
}
There's a UITableViewDataSource method called tableView:numberOfRows:inSections method.Just check for the state of the switch and return 1 if it's OFF or all the rows if it is ON. Just call the [tableView reloadData] method each time you switch ON and OFF. As simple as that.

How to select Multiple rows in UITableView?

I want multiple selection in UITableView and also its data into one array or in one dictionary...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if ([selectedCell accessoryType] == UITableViewCellAccessoryNone) {
[selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
[selectedIndexes addObject:[NSNumber numberWithInt:indexPath.row]];
} else {
[selectedCell setAccessoryType:UITableViewCellAccessoryNone];
[selectedIndexes removeObject:[NSNumber numberWithInt:indexPath.row]];
}
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
selectedIndexes has to be an array where you manage the selected cells indexes and utilize later accordingly.
Trying to do the same thing, but I'm seeing the "selected" checkmark accessory on other lines that were never selected when you scroll down the list. Also, deselecting one of the "phantom" items down the list causes the accessory to go away in the upper part of the list -- but the array is unaffected.
Here's how I have it implemented:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
if ([selectedCell accessoryType] == UITableViewCellAccessoryNone) {
[selectedCell setAccessoryType:UITableViewCellAccessoryCheckmark];
[selectedIndexes addObject:[NSNumber numberWithInt:indexPath.row]];
NSLog(#"IVC selectedIndexes AddObject # %d:", indexPath.row);
NSLog(#"IVC selectedIndexes: %#", selectedIndexes);
} else {
[selectedCell setAccessoryType:UITableViewCellAccessoryNone];
[selectedIndexes removeObject:[NSNumber numberWithInt:indexPath.row]];
NSLog(#"IVC selectedIndexes RemoveObject # %d:", indexPath.row);
}
[tableView deselectRowAtIndexPath:indexPath animated:NO];
}
EDIT: Added solution: You need to put this in your "cellForRowAtIndexPath" code:
if ([selectedIndexes containsObject:[NSNumber numberWithInt:indexPath.row]]) [cell setAccessoryType:UITableViewCellAccessoryCheckmark];

Refresh NSTableView After Click - Not Refreshing

I have an app with a UITableView, using both icons and disclosure buttons. I want to update the icon on a row with a "selected" icon, and update the previously-selected row with an "unselected" icon. I have the code in place, but when I click on the rows, it sets both rows to the "selected" state, even though via debugging I can see that my state variable is being set to the correct row. If I keep clicking rows I can sometimes get the "unselected" state to show. I suspect it's a refresh issue, but I've tried the setNeedsDisplay method on the cells and the tableView itself, but with no luck. Anyone run into this before? BTW, this is in the simulator (2.2.1) - haven't tried it on the device.
Here's the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
int newRow = [indexPath row];
int oldRow = [lastIndexPath row];
if (newRow != oldRow)
{
[[tableView cellForRowAtIndexPath:indexPath] setImage: [UIImage imageNamed:#"IsSelected.png"]];
c_oListPtr.c_sCurItem = [[tableView cellForRowAtIndexPath:indexPath] text];
[[tableView cellForRowAtIndexPath:lastIndexPath] setImage: [UIImage imageNamed:#"NotSelected.png"]];
[lastIndexPath release];
lastIndexPath = indexPath;
[[tableView cellForRowAtIndexPath:lastIndexPath] setNeedsDisplay];
[[tableView cellForRowAtIndexPath:indexPath] setNeedsDisplay];
[tableView setNeedsDisplay];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
Thanks
-Mike
Have you tried [tableView reloadData]?