UITableView checkmark in some particular row in every section - objective-c

I have a UITableView containing 'N' number of sections with 'N' no of rows in each section.
My requirement is:
When the table view page loads the 1st row in each section must be check-marked. The user then will have the option to select his choice in each section and that row in that particular section is check-marked.
How do I implement this functionality?

The information displayed in any particular row of a table is determined by the table's data source. Make sure that the data structure that you use for your data has some way of indicating that a given row has a check mark. Then just implement -tableView:cellForRowAtIndexPath: such that it determines whether a check mark should be displayed for the cell in question and adjusts the cell accordingly.
For example, let's say that the data is represented as an array of sections, and each section is an array of dictionaries. Each row, then, has its own dictionary. If a row is to have a check mark, its dictionary will have a checked entry set to YES; if it doesn't, that entry is NO. You can display the check mark as an image. Then you have:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyTableViewCell *cell = ... // code to get the cell
if (myData[indexPath.section][indexPath.row][#"checked"].boolValue == YES) {
cell.checkedImageView.image = self.checkmarkImage;
}
else {
cell.checkedImageView.image = nil;
}
return cell;
}
Putting the check mark in the first row of each section is just a matter of initializing your data so that the first entry in each section's array is checked and the others aren't.
You can change the checked cell by implementing -tableView:didSelectRowAtIndexPath: so that it scans through the array for the given section and unchecks any checked row, and then checks the selected row.
Of course, you don't have to represent your data using an array of arrays of dictionaries, and there's a good chance that you don't. That's fine -- the point here is just that you'll implement the functionality that you're after by implementing the table's delegate and data source such that they support the check mark, and that the presence or absence of the check mark in any particular row will be determined by some aspect of your table's data.

You can set your cell's accessoryType to a checkmark:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = ... // code to get the cell
// isCellSelectedAtIndexPath: is your custom method
// which encapsulates cell selection state logic
if ([self isCellSelectedAtIndexPath:indexPath])
{
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
else
{
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}

Related

table view data loading issue

I have a doubt in table view. I have placed a label & switch in table view cell. I set the switch value as NO by default. Now when table view is loaded in simulator the table view displays switch with NO value. Now I selected switch value as YES. But table view uses dequeue reusable cell method Property when table view is scrolled objects will reload every time now what will be the switch value will it be NO or YES?
It will be YES.
One more thing on scrolling tableview it not call reload method. Its just reusing already created tableview cells if you are using deque reusable cell method Property.
TableViewCells get destroyed and created where necessary when the table view gets scrolled.
When a cell gets destroyed as it goes out of the visible screen area, your switch control being a subview of the cell also gets destroyed.
So when you scroll back to one of your previously set switches, what you're actually seeing is another instance of a UITableViewCell with a switch view added to it, and so it looks like the switch value changed back to NO.
What you need is a third thing that remembers what the value of each switch should be in each row. If you're display a table of Core Data entity information, then perhaps you can define a property for your entity like "active". In that case, every time you change a switch value, you set your core data entity "active" property to the switch value e.g.:
-(UITableViewCell *)tableView:(UITableView)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
if(cell == nil)
{
// set switch control tag number (don't use 0)
}
// get switch control by tag number
// pseudocode
Engine *myEngine = [arrEngine objectAtIndex:indexPath.row];
mySwitchControl.active = myEngine.active;
...
}
// when you change switch value, remember to update your core data entity value
-(void)updateSwitchValue:(BOOL) newValue
{
// update value
}
Otherwise, you can simply use a NSMutableArray of bool values to identify which row each switch should be YES or NO:
// my header file (.h file)
#interface
{
NSMutableArray *arrSwitchValues;
}
// my implementation file (.m file)
-(UITableViewCell *)tableView:(UITableView)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
if(cell == nil)
{
// set switch control tag number (don't use 0)
}
// get switch control by tag number
// pseudocode
BOOL switchVal = [arrSwitchValues objectAtIndex:indexPath.row];
mySwitchControl.active = switchval;
...
}
// when you change switch value, remember to update your array
-(void)updateSwitchValue:(BOOL) newValue
{
// update value
}
Hope that helps.
to guarantee not have duplicated cells:
use this code in
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
as follows :
for(UIView *v in [cell subviews])
{
if([v isKindOfClass:[UILabel class]] ||[v isKindOfClass:[UISwitch class]])
[v removeFromSuperview];
}

Adding Section Headers to UITableView

Forgive the noob question, still learning.
I have a UITableView with a single array for data (approx 50). I'm looking to implement section headers but I just can't get my head around it. All the information I can find seems to vary greatly (there seems to be manes ways it can be implemented?) and I can't seem to piece it all together!
As ever I can't make out the Apple docs but I think that's down to my inexperience.
So a few questions:
I understand I need to state how many sections are needed, with a single array, would would be the best way?
Can I use a single array? Or am I going to need to break it down into numerous arrays, each with their own section?
Thanks in advance.
Code for cellForRowAtIndexPath for jonkroll
switch (section) {
case 0:
cell.textLabel.text = (NSString*)[tableViewArray objectAtIndex:row];
break;
case 1:
cell.textLabel.text = (NSString*)[tableViewArray objectAtIndex:row+3];
break;
case 2:
cell.textLabel.text = (NSString*)[tableViewArray objectAtIndex:row+17];
break;
}
The methods in the UITableViewDataSource protocol let you to define how the tableView renders your data.
Use numberOfSectionsInTableView: to tell your table how many sections it will have.
Use numberOfRowsInSection: to tell your table how many rows will be in each section.
Use cellForRowAtIndexPath: to tell your table what to render in a particular cell based on indexPath (indexPath is a structure that identifies a particular cell based on section and row)
So you say you have a single array that you want to display in more than one section. This is a very contrived example, but let's say you want rows 1-30 to be in the first section and rows 31-50 to be in the second section.
You can do the following:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
switch (section) {
case 0: return 30; break;
case 1: return 20; break;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
int section = [indexPath section];
int row = [indexPath row];
NSString* CellIdentifier = #"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
switch (section) {
case 0:
cell.textLabel.text = (NSString*)[array objectAtIndex:row];
break;
case 1:
cell.textLabel.text = (NSString*)[array objectAtIndex:row+30];
break;
}
return cell;
}
You application probably has an UITableViewDataSource and UITableViewDelegate (this is where you return the elements of the array and configure the number of sections, etc.). Within that class (or those classes if they're separate) there's two approaches you can take depending on what you'd like to do.
If you just want to have a title with the default look, implement tableView:titleForHeaderInSection: to return the title you want for each section.
If you want a custom view, implement tableView:viewForHeaderInSection: as well as tableView:heightForHeaderInSection: to return the custom view along with the height of the header views.
If you want a header consider using a UITableViewCustomCell, drag one into the nib where you have your tableView set up. Declare and link up in InterfaceBuilder.
IBOutlet UITableViewCell *cellOne;
#property (nonatomic, retain) IBOutlet UITableViewCell *cellOne;
Then you can use to assign the CellView to the Table view for your header.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if ([array count] == 0) return cellone;
You should look at the iPhoneCoreDataRecipes example that Apple puts out. They use a Tableview and show the data different ways. Being new at programming myself, I don't know how to provide the link to you, but it's in the iOS 5.0 Library under Data Management.

Remove unpopulated UITableViewCells?

Working with TableViews and have a two-parted question:
I have a TableView where there are only four cells with content. However the TableView continues down with about five or six more, empty, cells. Is there a way of removing these? What this would do, graphically, is remove all the lines below these 4 cells, while everything else stays the same.
Regard the following image, it has 2 populated cells and 7 extra lines below them, I want theses lines removed:
2.The four cells contain buttons. Because of this I want to remove the users ability to click/mark the entire cell. Is there such a "setting"?
Thank you, Tobias Tovedal
1.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 4;
}
2.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
You have to set 0 to the size of your footer to clear those "ghost" cells.
self.myTable.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
I am thinking of 2 ways to accomplish your first Q:
Set up TableView to be grouped and not plain (tableview will have round corners);
Make the separators color to match the background of the cells:
tableView.separatorColor = [UIColor whiteColor];// or whatever color you have
But you will have to manually add a line for each cells you are displaying.

Customize TableviewCell depending on section

How do I customize the background image of a UITableViewCell depending on the section, they are in? E.g. in section one, the cells are supposed to have a green .png image as a background image, whereas in section two, the cells are supposed to have a red .png image as background.
See Populating the Table View With Data for how to access and use section information.
When you have more then one section you implement some optional table view source methods to deal with sections.
Then when you create cell, check in which section it is and set it up accordingly, in:
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath;
In this method you can access indexPath.section and format your cell.
See Table View Programming Guide for more.
UIKit adds property section to NSIndexPath so you can get section from index path passed in to the above method (see the first example I linked).
example:
if(section == 0) {
background.image = [UIImage imageNamed:#"green.png"];
}
else if(section == 1) {
background.image = [UIImage imageNamed:#"blue.png"];
}

How to show multiple customcell and a custom section header in one uitableview?

I want to create a tableview like this. All sections have custom section header views.
The first row of first section contains a custom row rest of the first section cell's are another custom cell. Though every section will contain different type of cells.
So what is the best approach to achieve this while managing the speed of tableview? Currently I'm using custom cells using interface builder. Is there a way that I could add different things on different sections on cells?
Try to keep as few types of cells as you can. If one type cell is similar to another but with one or two extra labels, just set it all up in the same cell and keep the labels empty on the cell that doesn't need them. That way they can be in the same reuse queue. If the cells are different enough you might need to have more queues. Just instantiate them with a different cellIdentifier and they will get added to the queue for that identifier.
eg.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell;
if(indexPath.row == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:#"firstRowCell"];
if(!cell) {
cell = [[UITableViewCell alloc] inittWithFrame:CGRectZero reuseIdentifier:#"firstRowCell"];
}
// -- first cell setup
} else {
cell = [tableView dequeueReusableCellWithIdentifier:#"genericRowCell"];
if(!cell) {
cell = [[UITableViewCell alloc] inittWithFrame:CGRectZero reuseIdentifier:#"genericRowCell"];
}
// -- generic cell setup
}
// -- common cell setup
return cell;
}