UITableView adding grouped style and adding segments - iphone

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.

Related

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

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

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.

UITableView Separator Style Question

I have a tableview that is blank by default. User can add cells to it.
I want the separator lines to be clear when there are no cells, and grey when there are cells.
I am using this code:
if ([[self.fetchedResultsController fetchedObjects] count] == 0)
{
self.routineTableView.separatorStyle = UITableViewCellSeparatorStyleNone;
self.routineTableView.separatorColor = [UIColor clearColor];
}
else
{
self.routineTableView.separatorColor = [UIColor grayColor];
}
The problem is, when I launch the app with a blank table, and if I add cells, the grey lines are not there there until I restart the app. But if I start with cells there, then delete them, then re-add them, the lines are there. Any suggestions?
Maybe you are missing this?
...
else
{
self.routineTableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; // or you have the previous 'None' style...
self.routineTableView.separatorColor = [UIColor grayColor];
}
EDIT :
You need this but not only this... According to Apple Documentation :
The value of this property is one of the separator-style constants described in UITableViewCell Class Reference class reference. UITableView uses this property to set the separator style on the cell returned from the delegate in tableView:cellForRowAtIndexPath:.
That means the style wont change for cells that are already loaded. Just scrolling the table to force cells to redraw should make separators appearing...
You then have to :
set it BEFORE cell is inserted
OR
reload tableView when the first cell is added
which is not easy to do with a NSFetchedResultsController, you should look into its delegate for a solution... or change direction, like hiding the tableView until you have a result maybe...
EDIT 2 : You can also simply add this :
[self.tableView reloadData];
but that's a dirty workaround that will just reload full tableView, losing most benefits of NSFetchedResultsController...
A quick fix I usually do is:
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if ([tableView respondsToSelector:#selector(setSeparatorStyle:)]) {
[tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
}
}
This changes the boolean flag of whether there will be a separator or not. Put this in viewDidLoad:
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
And to make sure you've really made it go away, set the seperatorColor property to whatever the background color of the view and cell would be:
// If the background is white
self.tableView.separatorColor = [UIColor whiteColor];
So then even if somehow the above does not get called and the separator is still persisting - it would be the same color as what is behind it, therefore invisible.
Good luck.

How to display a set number of rows in UITableView?

How do i display set number of rows in a UITableView?
i.e if my data source has only 4 objects then i want the table to display on those 4 rows without any blank rows. any ideas?
thanks!
EDIT: i wasn't too clear about the question so..
So this is my table: http://i.stack.imgur.com/glkWZ.png ..
i want to display only the 3 rows and not the blank rows below it. The number of rows change depending on my data source.
any ideas how to go about doing so?
You have to change your table appearance, I think. Once you correctly set the numberOfSectionsInTableView: and tableView:numberOfRowsInSection: methods, you should change your viewDidLoad method adding this line:
[self.tableView setSeparatorStyle:UITableViewCellSeparatorStyleNone];
This way you will remove all lines from the table.
If you still want to make a line appear between lines, I suggest you to create a custom UITableViewCell, or to build a standard one adding a subview to mimic the line. Eg. something like this:
CGRect lineFrame = CGRectMake(0,cell.frame.size.height-1,cell.frame.size.width,1);
UIView *line = [[UIView alloc] initWithFrame:lineFrame];
line.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1];
[cell.contentView addSubview:line];
[line release];
Let me know if this helps.
Check the UITableView DataSource protocol, there are two relevant methods you have to implement:
– numberOfSectionsInTableView:
– tableView:numberOfRowsInSection:
The first one should return 1, the second one 4.
If you want to keep a set number of lines in your tableview and not display the extra blank lines, you could insert a empty footer view in viewdidload function.
self.tableview.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
I did not actually understand what you mean with "display on those 4 rows without any blank rows" but I guess what you ask is just a simple data retrieval process. I suppose the data source is NSarray.
-numberOfRowsInSection:(NSInteger)section{
return [MyArray count];
}
-cellForRowAtIndexPath(NSIndexPath*)indexPath{
NSInteger row=indexPath.row;
cell.textLabel.Text=[MyArray objectAtIndex:row]
return cell;
}
I assume you know what should be put in those blank spaces.I just wrote the major points.
try this
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 4
}
also implements the rest of delegate methods required to populate tableview..
Hope it helps you.......
You can use this
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 4
}
Or you this also
Check the UITableView DataSource protocol, there are two relevant methods you have to implement:
– numberOfSectionsInTableView:
–
tableView:numberOfRowsInSection:
The first one should return 1, the second one 4.
Or you can also use
GroupBy table in your view by changing the table style to gourpby table. use

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