How to animate table view cells when switching between buttons of UISegmentedControl? - iphone

My application is looking like the below image
I have 3 buttons in my segmented control. Assume that hitting the "Department" button will display 3 departments & hitting "Name" button will show 6 names.
I follow the below steps to make this..
Create UISegmentedControl by this code
segmentedControl = [[UISegmentedControl alloc] initWithItems:[NSArray arrayWithObjects:#"Department", #"Name", #"ID",nil]]; //Initialize Segmented Control
segmentedControl.segmentedControlStyle = UISegmentedControlStyleBar; //Define bar type (optional)
segmentedControl.selectedSegmentIndex = 0; //Define default clicked button
[segmentedControl addTarget:self action:#selector(segmentClicked) forControlEvents:UIControlEventValueChanged]; //Set target and define which method should called when tapping buttons
self.navigationItem.titleView = segmentedControl; //To add UISegmented Control in the title of the navigation bar
Define the method(segmentClicked) for UISegmented Control
segment = segmentedControl.selectedSegmentIndex;
if (segment==0) {
//Do something for Department tab
[self.tableView reloadData];
}
else if (segment==1) {
//Do something for Name tab
[self.tableView reloadData];
}
else {
//Do something for ID tab
[self.tableView reloadData];
}
Create the cells with reference to the value of segment in tableView: cellForRowAtIndexPath: method. (So that we can get various cells for each UISegmentedControl buttons)
if (segment == 0) {
cell.textLabel.text = [listOfDepartments objectAtIndex:indexPath.section]; //listOfDepartments is the NSMutableArray that contains list of Departments names
}
else if (segment == 1) {
cell.textLabel.text = [listOfNames objectAtIndex:indexPath.section]; //listOfNames is the NSMutableArray that contains list of person names
}
else {
cell.textLabel.text = [listOfIDs objectAtIndex:indexPath.section]; //listOfIDs is the NSMutableArray that contains list of person ID's
}
return cell;
So, finally i got the view showed in the above image.
When i press on the UISegmentedControl buttons, the table view reloads its cells & showing corresponding values perfectly. By default, the "Department" button was selected. If i tap the "Name" button(that is, table will show 6 cells instead of 3), The table changes immediately without any animations. It simply hide 3 cells of department names and showing 6 cells that displaying names of persons without any animations. I could not find a way to making the cell changes with smooth animations.
What should i implement to achieve the smooth animations?
Thanks in Advance

Use insertRowsAtIndexPaths:withRowAnimation: and deleteRowsAtIndexPaths:withRowAnimation: methods which has options for specifying some build-in cool animations.
typedef enum {
UITableViewRowAnimationFade,
UITableViewRowAnimationRight,
UITableViewRowAnimationLeft,
UITableViewRowAnimationTop,
UITableViewRowAnimationBottom,
UITableViewRowAnimationNone,
UITableViewRowAnimationMiddle,
} UITableViewRowAnimation;

It may help to try:
[self.tableView beginUpdates];
[self.tableView endUpdates];
in your segmentClicked method, instead of [self.tableView reloadData];
These methods sometimes animate table changes better.

Use the method reloadSections: withRowAnimation:
If you are having only one section then pass [NSIndexSet indexSetWithIndex:0] as a first argument in above method. In the second argument you can choose the animation type.

Related

how to set hidden property to NO for particular cell in tableView

I am new to iphone.I have a small doubt that is,I have a table view with 66 rows initially i placed a progress view to all rows but in viewdidload i set it to hidden for all those like below in tableViewClass(ShowProgressViewCont)
cell.progressView.hidden = YES;
here (cell) is the the reference of the CustomCell class.In this class i declare a progress view and setter and getter properties also be set here in this class
here in tableview there is a download button in each cell.If we click on that download button(for example in 66th cell).we have to remove the hidden property to the progress view for that particular 66th cell only.The remaining 65 cells should have the progress view in hidden only like that for all cells.
If any body know this please help me....
Are you familiar with the concept of table cells being reused?
viewDidLoad is not an appropriate place to manipulate the content of a single cell. It may work fine if the table is so small that all of its cells fit on the screen (in both orientations).
When there are more cells in the table than beeing displayed on the screen, then those cell that became invisible recently is being reused and displayed again.
So if there are 6 cells on the screen at a time then table cell no. 7 (sometimes 8) will be identical with cell no. 1.
cellForRowAtIndexPath would be a better place to hide/unhide certain views of a cell.
If it is a custom cell already then the cell's layoutSubViews could be appropriate, too. However, only in the tableViewController's cellForRowAtIndexPath you will have easy access to both, the table's data and the associated cell.
cellForRowAtIndexPath is called every time when a cell is about to become visible. Use the default reusing-mechanism to ensure that a proper cell object will be reused. It is pretty much straight forward.
Get the cell at index 65 and then cast it to your custom cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:64 inSection:0]];
YourCustomCell *customCell = (YourCustomCell *)cell;
customCell.progressView.hidden = NO;
First set the row number in your download button in CellForRowAtInedexPath
downloadButton.tag = indexPath.row
[downloadButton addTarget:self action:#selector(actionDownload:) forControlEvents:UIControlEventTouchUpInside];
in actionDownload, make the IndexPath from button.tag and get the cell from "cellForRowAtIndexPath:",
finally update via reloadRowsAtIndexPaths: withRowAnimation:
Hide your progress view in your custom cell means make the default property of every progress view is hidden ,and then your button click method .
CutomeCell *cell = (CutomeCell *)[[button superview] superview];
[cell.progressView setHidden:NO];
NSIndexPath *rowToReload = [[self tableView] indexPathForCell:cell];
NSArray* rowsToReload = [NSArray arrayWithObjects:rowToReload, nil];
[UITableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];
may this help you ...
your model should be tracking the progress for every button clicked. for purposes of this answer, let's say the model is held in a property called modelInformationArray (which would contain an array of objects that relate to each cell in the table)
when the download button is clicked for a cell, modelInformationArray is modified in such a way that its object knows a download is being processed for it.
that object reports the downloading processing in a member called downloadingProcessingStarted. there are many other ways to do that part.
to get to the answer to your question … to then unhide the progress view, you would do something as follows in your UITableViewDataSource implementation of tableView:cellForRowAtIndexPath: .
- (UITableViewCell*)tableView:tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
YourCustomCell* cell = ...
if ([[self.modelInformationArray objectAtIndex:indexPath.row] downloadingProcessingStarted])
cell.progressView.hidden = NO;
}

UITableViewCell Accessory Repeating?

In my app, I have a detailed view where the user can edit attributes of for example a person, their name, address etc.
In two cells, rather than being able to select them to edit their contents, they have a right accessory, a UISwitch, however sometimes, its inconsistent, but they replicate onto other cells in my last section.
I have been scanning my code dozens of times over with a fine comb and can't find the damn cause. What might cause this? Here is the code that I use to create the UISwitch on just a single cell:
if (indexPath.section == 0 && indexPath.row == 1)
{
cell.textLabel.text = #"Confirmed";
//Make the cell unselectable
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
//Create and add uiswitch
confirmedSwitch = [[UISwitch alloc] initWithFrame:CGRectZero];
[confirmedSwitch addTarget:self action:#selector(switchConfirmedStatus:) forControlEvents:UIControlEventValueChanged];
[confirmedSwitch setOn:[venue.isConfirmed boolValue]];
cell.accessoryView = confirmedSwitch;
}
So you expect it to only show up on that cell, see anything odd with that code? I have checked my if statements and all my brackets indexPath checks are correct.
Anyone see this before or have any clues?
The problem is because of reusability issues in the UITableView. You probably use the same identifier for all cells and this causes the cellForRowAtIndexPath to be implemented in other rows (when you scroll up and down).
This is a common problem when you are developing applications with tableView and there are plenty of questions like this on StackOverflow.
As a general solution, you will need to do either of these.
Use different identifiers when you assign dequeueReusableCellWithIdentifier for each cell. This is fairly simple, and you just need to assign different identifiers for them.
Subclass you UITableViewController, and create your own CustomTableViewController which will implement the necessary components in the cell. I believe you will need to override the set Layout Subviews method.
Take a array in view will appear and add object 0 for this row and 1 for all other rows and then in cellForRowAtIndexPath check if array has 0 at that index if it has then put switch otherwise nill..
for(int i =0;i<10;i++)
{
if(i==1)
{
[arrayForSwitch addObject:#"0"];
}
else
{
[arrayForSwitch addObject:#"1"];
}
}
then in cellForRowAtIndexPath write condition
if([arrayForSwitch objectAtIndex:indexPath.row isEqualToString:#"0"])
{
cell.accessoryView = confirmedSwitch;
}
else
{
cell.accessoryView =UITableViewCellAccessoryNone;
}
it will now remain same

UITableView adding grouped style and adding segments

I need to create a grouped tableview Controller some thing similar to this image
I have identified that this tableview has 2 segments, so i added 2 segments and 2 rows each for each segment.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(section == 0) return 2;
else return 2;
}
1.) The problem i have is, how to add the Label on top of the 1st segment of the tableview.
I have to add 2 buttons in between the 2 Groups (tableviews), i know how to add one button, but how do you add 2 ?
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
if (section == 0) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button setTitle:#"Hello" forState:UIControlStateNormal];
// How to add the 2nd button ?
return button;
}
return nil;
}
3.) When i added the group table view with 2 segments, i didn't get the round edges in the cells, how do i get that ?
4.) I need to have the edit feature (so i could delete records) ONLY for the 2nd segment. So when i click on the edit button, i should be able to delete records only on the 2nd segment. Is this possible ? if so how do i do this ?
I assume you are talking about the Header for the Section? In that case, use the TableView delegate method titleForHeaderInSection
Don't use the Footer to add the buttons. If you need buttons "in between the cells", just create a new section with no header title and one row to two rows and put the buttons as parts of the rows.
Make sure you have the tableView style set properly:
initWithStyle:UITableViewStyleGrouped];
Use the tableview delegate method canEditRowAtIndexPath to allow/disallow editing (deleting) of a cell.
1) About the label, are you trying to add the label right above it, or directly on top of it?
Try this, I'm not sure if the syntax is correct, but if you mess with it, it should work.
UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, w, h)];
[titleLabel setText:#"TITLE"];
[**your UITableView** addSubview:titleLabel];
[self.view addSubview:**your UITableView**];
[titleLabel release];
3) the round edges... I'm not too sure about this, but it is either 1. your xcode version, maybe the round edges are in a newer/older version of xcode so you may have to upgrade...
2. In the example they are using a custom tableview that they made themselves, or its a different type of UITableView.
4) You can have a boolean function that checks for permissions, like if the user pressed one part or the other, the boolean function checks, this could be used to disable/enable the edit part of your function.

Is it possible to accept a button tag to be in some range iphone sdk

In my application I'm doing dynamic resizing of cells and label in it depending upon the text in it.
I'm adding button to cells in uitableview.
I'm taking the label instance and button instance in a new label and button variable respectively and setting their frames to arrange them properly after resizing.
if(cel==nil)
{
//some code
original_label=[[UILabel alloc]init];
original_label.tag=111;
//SOME MORE CODE GOES HERE
original_button=[[UIButton alloc]init];
original_button.tag=222;
//SOME MORE CODE GOES HERE
}
new_label=(UILabel *) [cell viewWithTag:111]; //This' how I'm taking the label instance on cell and below button instance on cell in new variables
new_button = (UIButton * ) [cell viewWithTag:222];
Earlier I kept the tags of all the buttons on cells same, so it was easier to get button instances on cells properly and were being arranged properly. But now I want to recognize these buttons separately as I'm adding some functionality on button_click. I'm giving the buttons that are added to the cells incremental tags[1,2,3...9 and so on]. Now, how can I take these button tags in some range like[suppose 1-9]?
Can anybody help?
Thanks in advance.
You can keep the button tags the same as you had before.
Instead, in the button_click method, figure out which row the button is in like this:
- (void)button_click:(UIButton *)button
{
UITableViewCell *cell = (UITableViewCell *)[[button superview] superview];
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
//code to handle this indexPath.section and indexPath.row...
}
This assumes you have added the button to cell.contentView which is what the first superview gets. The second superview gets the cell.
The addTarget for the button should look like this (note colon after button_click):
[original_button addTarget:self action:#selector(button_click:) forControlEvents:UIControlEventTouchUpInside];

Wipe a delete button out of table view cell

when pressing a row delete button on a table view, I do some validation, and if the user chooses to cancel the operation it all should rollback. Not only want to keep that row (what is happening), but also make disappear the delete button leaving only the "-" round button. How can I do that?
once again, thank you.
Assuming you are implementing your validations in tableView:commitEditingStyle:forRowAtIndexPath: method of your UITableViewDatasource protocol object, you should be able to set the editingAccessoryType and editingAccessoryView on the cell.
//After validation fails....
UITableViewCell *aCell;
aCell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
// validations are done and you need to ignore the delete
if ( aCell.showingDeleteConfirmation ){
aCell.editingAccessoryView = nil;
aCell.editingAccessoryType = UITableViewCellAccessoryNone;
}
If you want, you can wrap the changes in an animation block to animate the change.
Alternatively, you could toggle the editing state of the cell.
//After validation fails....
UITableViewCell *aCell;
aCell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
if ( aCell.showingDeleteConfirmation ){
aCell.editing = NO;
aCell.editingAccessoryView = nil;
aCell.editing = YES;
}