Hiding the table view cells with switch ON/OFF in iPhone - 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.

Related

How to insert row to n number of sections dynamically in UITableview

How to update number of rows in
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
}
When it will expand increase number of rows.
`- (void) rotateButtonToExpanded:(UIButton*)aButton section:(int)aSection{
// Rotate the button with animation.
[UIView beginAnimations:ROTATE_TO_EXPAND context:nil];
[UIView setAnimationDuration:ANIMATION_DURATION];
aButton.transform = CGAffineTransformMakeRotation(M_PI*2.5);
[UIView commitAnimations];
// Save the state (expanded or collapsed) of button with index path as key.
BOOL isExpanded=![[mStateOfNodes objectAtIndex:aSection] isExpanded];
[[mStateOfNodes objectAtIndex:aSection] setIsExpanded:isExpanded];
NSArray*theDataOfChildCells=[[self.mNodes objectAtIndex:aSection] valueForKey:CHILD_NODES];
for (int i=0; i<theDataOfChildCells.count; i++) {
mNumberOfCells++;
[self beginUpdates];
NSIndexPath*theIndexPath=[NSIndexPath indexPathForRow:i inSection:aSection];
[self insertRowsAtIndexPaths:[NSArray arrayWithObject:theIndexPath] withRowAnimation:UITableViewRowAnimationMiddle];
[self endUpdates];
}
}`
used reload data methods,
[self.tableview reloadData];
Use Following code that use for add row in UITable with specific row and section
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:rowNO inSection:SectionNO];
[self.tblView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
rowNO=rowNO+1;
[self.tblView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
[self.tblView reloadData];

NSFetchedResultsControllerDelegate and Alternating Table View Cells

I have a UITableView that updates from a NSFetchedResultsController. The UITableView has alternating row colours for even and odd rows. I need to add support for the insertion and deletion of objects, so I implemented the NSFetchedResultsControllerDelegate to handle this. However, now my alternating colour scheme fils after inserting anywhere but at the end. Any ideas on how to solve this without reloading the table view (and not loose my animations)?
Here is my code thus far:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomTableViewCell *cell = ...;
indexPath.row % 2 == 0 ? [cell odd] : [cell even];
return cell;
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)object
atIndexPath:(NSIndexPath *)deleteIndexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)insertIndexPath
{
switch(type)
{
case NSFetchedResultsChangeInsert:
[self.mainTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:insertIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.mainTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:deleteIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
The followings are what I did for one of my projects:
- (void)reloadRowsFromIndex:(NSUInteger)index {
NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
for (NSInteger i = index; i < [items count]; i++) {
[indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
}
[tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
[indexPaths release];
}
reloadRowsFromIndex: is called within tableView:commitEditingStyle:forRowAtIndexPath:, with the first index path being changed.

tablerow delete but still showon in table view

my data is show on the table whn i select data to delet its delted from database but not from table , i go back to other view and again come to the delete table view then delete data is not show again
i am using this code ...
- (void)deleteRowsAtIndexPaths:(NSArray *)indexPath withRowAnimation:(UITableViewRowAnimation)animation
{
NSLog(#"Hello");
}
-(void) tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
// int row = [indexPath row];
[self.table beginUpdates];
if (editingStyle == UITableViewCellEditingStyleDelete)
{
Hadits *delHadit = [self.allBookMarks objectAtIndex:indexPath.row];
dbAccess *dbmethods = [[dbAccess alloc] init];
NSInteger delHaditid = delHadit.haditid;
[dbmethods deleteBookMark:delHaditid];
[dbmethods release];
}
[self deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self.table endUpdates];
NSLog(#"Hello");
[self.table reloadData];
}
...Help needed..
Regards Haseeb
in view will appear prepare your array which having record and in commitEditing add one line.
[self viewWillApear:YES];
and in viewWillAppear add this line
[yourTable reloadData];
after fetching data from db.
There is little mistake (or I think the relevant code is not shown). You have deleted the entry from the database, but I think you have missed to delete the same from your array which acts as your tableview datasource.
-(void) tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.table beginUpdates];
if (editingStyle == UITableViewCellEditingStyleDelete)
{
// [self.table deleteRowsAtIndexPaths:[NSArray arrayWithObject: indexPath] withRowAnimation:UITableViewRowAnimationFade];
Hadits *delHadit = [self.allBookMarks objectAtIndex:indexPath.row];
dbAccess *dbmethods = [[dbAccess alloc] init];
NSInteger delHaditid = delHadit.haditid;
[dbmethods deleteBookMark:delHaditid];
[dbmethods release];
[self.allBookMarks removeObject:delHadit];/// change of code
}
//[self.table reloadData];
[table endUpdates];
}

How update rows with reloadRowsAtIndexPath

I'm trying to delete cell with a Button.
Here is the implementation of a cell.
- (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];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
btn.frame = CGRectMake(0.f, 0.f, 30.f, 30.f);
[btn addTarget:self
action:#selector(btnTouched:)
forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:btn];
cell.tag = indexPath.row;
}
return cell;
}
- (void)btnTouched:(UIButton *)sender
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:sender.tag inSection:0];
[_myMutableArray removeObjectAtIndex:sender.tag];
[_tableView beginUpdates];
[_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationLeft];
[_tableView endUpdates];
}
This works well until I've delete a row, the button isn't reloaded so after a delete, I don't delete the good index. I tried to put reloadRowsAtIndexPaths:withRowAnimation: for visible indexPath after the endUpdates method and it works very well. But the delete animation became ugly by the reloadRows animation (even if I set it to NO).
So is there a way to reload cells without reloadCellsAtIndexPath. Or delete a rows without using tags.
Thx a lot.
You should be able to lookup the index of the cell by using logic similar to the following:
NSIndexPath *indexPath = [_tableView indexPathForCell:(UITableViewCell *)[sender superview]];
With this approach, you would not need to store the value of the row index in the cell tag.
To just reload the table (and thus all its cells), you could try just using:
[_tableView reloadData];

How do I popViewControllerAnimated after a delay?

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