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

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];

Related

scrollToRowAtIndexPath:atScrollPosition:animated scrolling too slow

Based on the page change of a paged UIScrollView, I'm calling scrollToRowAtIndexPath:atScrollPosition:animated to the table specifics for that page that's in display.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat pageWidth = self.scrollView.frame.size.width;
int page = floor((self.scrollView.contentOffset.x - pageWidth/2)/pageWidth)+1;
self.pageControl.currentPage = page;
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:page];
[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
}
However, the animation of the automatic scrolling is happening too slow. Is there a way to make this animation more snappy?
A fast solution might be:
[UIView animateWithDuration:aSmallValue animations:^{
[self.tableView scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionTop
animated:NO];
}];

UITableViewRowAnimationFade Not Working

So, this issue follows on from a previous issue, but I decided to post a new question to keep things relevant and tidy.
Basically, when the following piece of code is called, there is no difference between UITableViewRowAnimationFade and UITableViewRowAnimationNone:
- (void) setEditing:(BOOL)editing animated:(BOOL)animated
{
[tvController.tableView beginUpdates];
if (editing == YES) {
[tvController.tableView deleteRowsAtIndexPaths:[settingsArray objectAtIndex:0] withRowAnimation:UITableViewRowAnimationFade];
}else {
UITableViewRowAnimation animation = animated ? UITableViewRowAnimationFade : UITableViewRowAnimationNone;
[tvController.tableView reloadRowsAtIndexPaths:[settingsArray objectAtIndex:0] withRowAnimation:animation];
[tvController.tableView reloadSectionIndexTitles];
self.navigationItem.hidesBackButton = editing;
}
[tvController.tableView endUpdates];
}
Greatly appreciate any help. It still enters editing mode, but does not animate into it, depsite YES being passed into animated.
EDIT: The animation works fine when I'm actually deleting things using the following code:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSString* documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *stuff = [documentsPath stringByAppendingPathComponent:#"stuff.plist"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:stuff];
if (fileExists) {
NSMutableDictionary *propertyList = [[NSMutableDictionary alloc] initWithContentsOfFile:enteredPlaces];
[propertyList removeObjectForKey:[[settingsArray objectAtIndex:1] objectAtIndex:indexPath.row]];
[propertyList writeToFile:stuff atomically:YES];
}
[[settingsArray objectAtIndex:1] removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
}
}
It just doesn't work when the user presses the edit button and the table goes into editing mode, the tableview just snaps statically into edit mode.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[db DeleteData:[NSString stringWithFormat:#"%d",indexPath.row]];
[data removeObjectAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation: UITableViewRowAnimationFade];
}
}
I have same scenario in my application, I was facing the similar issue. I guess below function will solve your issue :
- (void) setEditing:(BOOL)editing animated:(BOOL)animated
{
[tvController.tableView setEditing:editing animated:animated]; //this LOC is added
[tvController.tableView beginUpdates];
if (editing == YES) {
[tvController.tableView deleteRowsAtIndexPaths:[settingsArray objectAtIndex:0] withRowAnimation:UITableViewRowAnimationFade];
} else {
UITableViewRowAnimation animation = animated ? UITableViewRowAnimationFade : UITableViewRowAnimationNone;
[tvController.tableView reloadRowsAtIndexPaths:[settingsArray objectAtIndex:0] withRowAnimation:animation];
[tvController.tableView reloadSectionIndexTitles];
self.navigationItem.hidesBackButton = editing;
}
[tvController.tableView endUpdates];
}
-(void)deleteRecord:(NSInteger)recordNo:(NSInteger)sectionNo:(BOOL)isEditMode:(BOOL)isAnimate {
if(isEditMode){
NSIndexPath *indexP=[NSIndexPath indexPathForRow:recordNo inSection:sectionNo];
[tvController.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObjects:indexP, nil] withRowAnimation:UITableViewRowAnimationLeft];
}
else {
if(isAnimate)
[tvController.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexP, nil] withRowAnimation:UITableViewRowAnimationFade];
else
[tvController.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexP, nil] withRowAnimation:UITableViewRowAnimationNone];
[tvController.tableView reloadSectionIndexTitles];
self.navigationItem.hidesBackButton = editing;
}
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(reload) userInfo:nil repeats:NO];
}
-(void)reload {
[table reloadData];
}
if the only thing that you are annoyed by is the fact that the delete doesn't fade, it is because you are anticipating something that the interface doesn't provide.
you mentioned that you know individual cells can be set to be non-editable, and this is the standard way to do this. the mechanism simply does not anticipate not using the UITableViewDataSource to provide the information about what to display (or, in your case, what is in the data being changed) simply by hitting the edit/done button.
by trying to combine the two, you are confusing the animation that is supposed to happen.
probably the best you can do is something like the following (and the animation duration and length could possibly be 0, since you're asking for separate animation in the tableView), which will cause your animation to occur after the animation that opens up editing mode.
- (void) setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated]; // possibly not necessary depending upon your class hierarchy
[tvController.tableView setEditing:editing animated:animated];
[UIView animateWithDuration:0.25 delay:0.05 options:UIViewAnimationCurveLinear
animations:^{
[tvController.tableView beginUpdates];
if (editing == YES) {
[tvController.tableView deleteRowsAtIndexPaths:[settingsArray objectAtIndex:0] withRowAnimation:UITableViewRowAnimationFade];
} else {
UITableViewRowAnimation animation = animated ? UITableViewRowAnimationFade : UITableViewRowAnimationNone;
[tvController.tableView reloadRowsAtIndexPaths:[settingsArray objectAtIndex:0] withRowAnimation:animation];
[tvController.tableView reloadSectionIndexTitles];
self.navigationItem.hidesBackButton = editing;
}
[tvController.tableView endUpdates];
}
completion:nil];
}

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.

Animate adding/removing UISearchBar to/from UITableView tableViewHeader

I have a subclass of UITableViewController. I have code that can add/remove a UISearchBar to/from the tableHeaderView of my tableView. Here's the code I have to perform these tasks:
self.tableView.tableHeaderView = uiSearchBar; //Make the search bar appear
self.tableView.tableHeaderView = nil; //Make the search bar disappear
The problem is that I want the adding/removing of the UISearchBar to be animated; slide into view from the top when I add it then slide upwards and out of view when I remove it instead of just appearing and disappearing. Any suggestions?
Thanks.
I was finally able to figure this out. Turned out to be pretty simple. Instead of adding the UISearchBar to the table header, I insert it into the first cell of the table with animation UITableViewRowAnimationTop and remove it using the same method. This results in the bar sliding in and out from the top. Here is the code that makes the bar appear:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.baseUiTableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
[self.baseUiTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
And here is the code that removes the search bar:
[uiSearchBar resignFirstResponder];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.baseUiTableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
A much simpler way that is also suitable for UITableViewStyleGrouped (plus doesn't require changing the number of rows) is to animate the contentInset of the table:
CGFloat h = uiSearchBar.bounds.size.height;
UITableView *tv = self.tableView;
if (tv.tableHeaderView)
{ // hide bar
[UIView animateWithDuration:0.3 animations:^{
tv.contentInset = UIEdgeInsetsMake(-h, 0, 0, 0);
} completion:^(BOOL finished) {
tv.contentInset = UIEdgeInsetsZero;
tv.tableHeaderView = nil;
[tv scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
}];
}
else
{ // show bar
uiSearchBar.frame = CGRectMake(0, -h, tv.frame.size.width, h);
[UIView animateWithDuration:0.3 animations:^{
[tv scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO];
tv.tableHeaderView = uiSearchBar;
}];
}
I know this is three years after the OP asked the question, but since this is a good alternative to achieve the desired effect, I thought it might be useful for others meeting the same problem.
Try having your table view scroll—animated—so that only the row below the search bar is visible, then remove the search bar and scroll to the same row without animation.

Add a row dynamically in TableView of iphone

I need to add a new row in the tableview when i select a row in the table.
Am i suppose to use the following method???
- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
What shoud i write inside the method to add a new row.?
Please do help me,
Thanks in advance
Shibin.
When I add a row dynamically, I use insertRowsAtIndexPaths: here is an example function
- (void) allServersFound {
// called from delegate when bonjourservices has listings of machines:
bonjourMachines = [bonjourService foundServers]; // NSArray of machine names;
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
int i = 0;
for (NSArray *count in bonjourMachines) {
[tempArray addObject:[NSIndexPath indexPathForRow:i++ inSection:0]];
}
[[self tableView] beginUpdates];
[[self tableView] insertRowsAtIndexPaths:(NSArray *)tempArray withRowAnimation:UITableViewRowAnimationNone];
[[self tableView] endUpdates];
[tempArray release];
}
If you are filling your table from an array, you can just add an element to your array and call [myTable reloadData]
reload data is nice and simple, but does not animate as far as I can tell...
ReloadData can add row in teble view but if you want some animation when row add then you should use these lines of code.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[tempArray addObject:[NSIndexPath indexPathForRow:indexPath.row+1 inSection:0]];
[mainArray insertObject:#"new row" atIndex:indexPath.row+1];
[[self tableView] beginUpdates];
[[self tableView] insertRowsAtIndexPaths:(NSArray *)tempArray withRowAnimation:UITableViewRowAnimationFade];
[[self tableView] endUpdates];
}