stuck at 3rd level of hierarchal tableview data - ios

I am developing app which is using storyboard and using two UITableView and one Label UIViewController. This app take data from the .plist file. I am able to retrieve data from .plsit show in first table and the according to the selected row data shown on second table but when I click to view the detail second table only one array strings I can view and can't view others. here is the sample for understating. A > AA > AAA and B > BB > BBB.
I have three topics in the first table i.e. Lumber Puncture, Urinary catheterization and veni puncture. Now when I click on each cell it displays me data in second UITableView according to the cell. Lets suppose showing me following data:
introduction
indication
equipments
etc
Now when I click the introduction of my Lumber puncture data it shows me detail of lumber puncture from the .plist array data. But if I click on the Urinary catheterization introduction on the second data cell, it also shows me the first Lumber puncture detail. So how can I solve this problem? kindly help me with your detail answers as I am new to develop iOS apps. Thanks
Here is some code for the first table and passing data to second table.
#implementation ViewController
{
NSArray *tableData;
NSArray *Components_Procedure;
}
#synthesize tableView1;
- (void)viewDidLoad
{
[super viewDidLoad];
// Find out the path of recipes.plist
NSString *path = [[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"plist"];
// Load the file content and read the data into arrays
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
tableData = [dict objectForKey:#"Procedure"];
Components_Procedure = [dict objectForKey:#"Component"];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ProcedureCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Procedure"]) {
NSIndexPath *indexPath = [self.tableView1 indexPathForSelectedRow];
Components *destViewController = segue.destinationViewController;
destViewController. componentArray= [Components_Procedure objectAtIndex:indexPath.row];
}
}
#end
Second table code and passing detail data to UIViewcontrollers UILables
#implementation Components
{
NSArray *detail;
}
#synthesize tableView2;
#synthesize componentArray;
- (void)viewDidLoad
{
[super viewDidLoad];
// Find out the path of recipes.plist
NSString *path = [[NSBundle mainBundle] pathForResource:#"recipes" ofType:#"plist"];
// Load the file content and read the data into arrays
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
detail = [dict objectForKey:#"LumberPuncture"];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [componentArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"ComponentCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [componentArray objectAtIndex:indexPath.row];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"Detail"]) {
NSIndexPath *indexPath = [self.tableView2 indexPathForSelectedRow];
DetailView *destViewController = segue.destinationViewController;
destViewController.headerName = [componentArray objectAtIndex:indexPath.row];
destViewController.contentName = [detail objectAtIndex:indexPath.row];
}
}
#end
and detail UIViewController class
#import "DetailView.h"
#implementation DetailView
#synthesize headerLabel;
#synthesize headerName;
#synthesize contentLabel;
#synthesize contentName;
- (void)viewDidLoad
{
[super viewDidLoad];
// Set the Label text with the selected recipe
headerLabel.text = headerName;
contentLabel.text = contentName;
}
#end

You need to use both methods, in didSelectRowAtIndexPath you should call [self performSegueWithIdentifier:#"identifier" sender:self];
In the same View Controller you should have the prepareForSegue method grab the destinationViewController
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath (NSIndexPath *)indexPath
{
self.someProperty = [self.someArray objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"segueID" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
UIViewController *vcToPushTo = segue.destinationViewController;
vcToPushTo.propertyToSet = self.someProperty;
}
Just add this method:
– tableView:didSelectRowAtIndexPath:
Typically, you use “didSelectRowAtIndexPath” method, which is invoked after user selects a row, to handle the row selection and this is where you add code to specify the action when the row is selected.
This and the "willSelectRowAtIndexPath" methods are used for row selection. The only difference is that “willSelectRowAtIndexPath” is called when a specified row is about to be selected. Usually you make use of this method to prevent selection of a particular cell from taking place.

Related

custom cell not being displayed

So i created a custom cell (using the .xib file) and linked it using a custom controller class and I also didn't forget to write in the cell identifier. I also gave the same cell identifier in my table view controller prototype cell. In the custom cell controller class I just have an outlet to a text label in the .h file. Below is the code for my table view controller. When I run the app, the custom cells are not displayed but there are cells there because i can click on them (but they are just white). What am I doing wrong, why aren't the custom cells displaying?
If I use the default cells (not custom), then everything works fine. So the problem is that I'm not using my custom cells correctly somewhere.
#import "ListmaniaTableViewController.h"
#import "ListmaniaTableViewCell.h"
#interface ListmaniaTableViewController ()
#property (strong, nonatomic) NSMutableArray *tasks; //of task object
#end
#implementation ListmaniaTableViewController
- (void)viewDidLoad{
[super viewDidLoad];
task *task1 = [[task alloc] init];
task1.taskDescription = #"TASK 1";
[self.tasks addObject:task1];
task *task2 = [[task alloc] init];
task2.taskDescription = #"TASK 2";
[self.tasks addObject:task2];
task *task3 = [[task alloc] init];
task3.taskDescription = #"TASK 3";
[self.tasks addObject:task3];
}
- (NSMutableArray *)tasks{
if(!_tasks){
_tasks = [[NSMutableArray alloc] init];
}
return _tasks;
}
/*- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
}
return self;
}*/
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([segue.identifier isEqualToString:#"Add New Item"]) {
}
}
- (void)addNewTask:(task *)newTask{
[self.tasks addObject:newTask];
}
#pragma mark - Table view data source
- (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 [self.tasks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
ListmaniaTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
if(!cell){
[tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];
cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
}
return cell;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(ListmaniaTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
task *task = [self.tasks objectAtIndex:indexPath.row];
NSString *taskLabel = task.taskDescription;
cell.taskLabel.text = taskLabel;
}
#end
But the
[self.tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];
in viewDidLoad:.
The code you have in tableView:willDisplayCell:forRowAtIndexPath: method should be in tableView:cellForRowAtIndexPath: method. Like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
ListmaniaTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
if(!cell){
[tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];
cell = [tableView dequeueReusableCellWithIdentifier:#"ListmaniaCell" forIndexPath:indexPath];
}
task *task = [self.tasks objectAtIndex:indexPath.row];
NSString *taskLabel = task.taskDescription;
cell.taskLabel.text = taskLabel;
return cell;
}
I figured out the problem. I had an outlet in the custom cell that was doubly linked. I also moved the line below into viewdidload as suggested by #dasdom
[self.tableView registerNib:[UINib nibWithNibName:#"ListmaniaTableViewCell" bundle:nil] forCellReuseIdentifier:#"ListmaniaCell"];

Show if tableview cell have been clicked before?

I'm developing an app with a news feed.
This is a PFQueryTableView loading content from parse.com.
I also have a detail ViewController attached with a segue.
My question is:
How can I show that there is a cell that hasn't been clicked before?
Like in the Mail application in IOS.
Here's a picture:
http://i.stack.imgur.com/vO2N3.png
- (id)initWithCoder:(NSCoder *)aCoder
{
self = [super initWithCoder:aCoder];
if (self) {
// Custom the table
// The className to query on
self.parseClassName = #"Nyhet";
// The key of the PFObject to display in the label of the default cell style
self.textKey = #"Rubrik";
// Whether the built-in pull-to-refresh is enabled
self.pullToRefreshEnabled = YES;
// Whether the built-in pagination is enabled
self.paginationEnabled = YES;
// The number of objects to show per page
self.objectsPerPage = 10;
}
return self;
}
- (UIStatusBarStyle)preferredStatusBarStyle
{
return UIStatusBarStyleDefault;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Change button color
sidebarButton.tintColor = [UIColor whiteColor];
// Set the side bar button action. When it's tapped, it'll show up the sidebar.
sidebarButton.target = self.revealViewController;
sidebarButton.action = #selector(revealToggle:);
// Set the gesture
[self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (PFQuery *)queryForTable
{
PFQuery *query = [PFQuery queryWithClassName:self.parseClassName];
// If no objects are loaded in memory, we look to the cache first to fill the table
// and then subsequently do a query against the network.
/* if ([self.objects count] == 0) {
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
}*/
[query orderByDescending:#"Prioritering"];
return query;
}
// Override to customize the look of a cell representing an object. The default is to display
// a UITableViewCellStyleDefault style cell with the label being the first key in the object.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"Rubrik"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"Detaljer"];
return cell;
}
- (void) objectsDidLoad:(NSError *)error
{
[super objectsDidLoad:error];
NSLog(#"error: %#", [error localizedDescription]);
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
PFObject *object = [self.objects objectAtIndex:indexPath.row];
Recipe *recipe = [[Recipe alloc] init];
recipe.name = [object objectForKey:#"Rubrik"];
recipe.prepTime = [object objectForKey:#"Text"];
recipe.detaljer = [object objectForKey:#"Detaljer"];
recipe.rubriker = [object objectForKey:#"Rubrik"];
destViewController.recipe = recipe;
}
}
#end
I think it's better use custom UITableViewCell example:
CustomTableViewCell.h
#interface CustomTableViewCell : UITableViewCell
#property(assign) bool beforeClicked
#end
CustomTableViewCell.m
#import CustomTableViewCell.h
#implementation CustomTableViewCell
#synthesize beforeClicked;
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
}
return self;
}
#end
And, example:
CustomTableViewCell.h //add this header
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
{
static NSString *simpleTableIdentifier = #"RecipeCell";
CustomTableViewCell *cell = (CustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = (CustomTableViewCell *)[[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
UILabel *nameLabel = (UILabel*) [cell viewWithTag:101];
nameLabel.text = [object objectForKey:#"Rubrik"];
UILabel *prepTimeLabel = (UILabel*) [cell viewWithTag:102];
prepTimeLabel.text = [object objectForKey:#"Detaljer"];
cell.beforeClicked = NO;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
UITableViewCell *myCell = [tableView cellForRowAtIndexPath:indexPath];
myCell.beforeClicked = YES;
}
Two solutions come to mind.
The simpler solution would be using an NSMutableArray to hold all visited cells. In didSelectRowAtIndexPath: do this :
if (![visitedCellsArray containsObject:[NSNumber numberWithInt:indexPath.row]])
[visitedCellsArray addObject:[NSNumber numberWithInt:indexPath.row]];
Then set a backgroundColor to your cell (just a suggestion, you may use any UI indicator - dot, color, etc) in your cellForRowAtIndexPath:
Second, might not be conducive to your purpose. I don't really know if the dictionary you are using is mutable or not, and whether adding keys will have any effect on your flow of control. But If adding a key is possible, add a key like #"seen" and set it with [NSNumber numberWithBool:YES] in didSelectRowAtIndexPath:, and in cellForRowAtIndexPath: add appropriate UI indication based on the value of this key. This method is better memory wise.
I'd give your PFReceipt objects a property BOOL new.
Then just get and set that property and in cellForRow you set the font based on the vale of the property.
clean and even persistent.
...
so to reiterate:
modify PFReceipt object to have a property new
modify - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object
...
cell.clickedBefore = !receipe.new;
mark receipes as no longer new when shown
...
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
...
PFObject *object = [self.objects objectAtIndex:indexPath.row];
selectedCell.clickedBefore = !object.new;
None of the solutions provided take into account that there may be more than one user of the app. If you store a "read" or "new" property in the object, this will only show if ANYBODY has read it. So if Jane reads it, Mark will see it as read.
To handle this separately for all users, you need another parse class to handle reading status. This gets a little complex to implement, but it is the only way to solve it all on the server.
Another option would be to store a read status list on every client. This means some kind of local persistent store that knows what recipes are read, and compare this to the data fetched from Parse.

My table view is loading the detail view in a dark screen

So i have a table view hooked up to a plist with urls. When I click on the table view cells i want it to take me to the detail view, but the only problem right now is when i click on the cell to take me to the detail view it just loads a dark screen with nothing on it. I don't receive any errors on the compiler so i have no idea what is wrong. I have reset the stimulator and tried restarting my computer but now I'm starting to think there is something wrong with the code. Can someone help?
TableViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
NSString *myListPath = [[NSBundle mainBundle] pathForResource:#"myList" ofType:#"plist"];
tableData = [[NSArray alloc]initWithContentsOfFile:myListPath];
NSLog(#"%#",tableData); }
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [tableData count]; }
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [tableData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cell"];
if( cell == nil )
{
NSLog(#"Cell Creation");
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"cell"];
}
//Set Data For each Cell
cell.textLabel.text = [[tableData objectAtIndex:indexPath.row]objectForKey:#"cellName"];
cell.detailTextLabel.text = [[tableData objectAtIndex:indexPath.row]objectForKey:#"cellSubtitle"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Index Selected,%d",indexPath.row);
WebViewController *View = [[WebViewController alloc] init];
NSString *urltoPass = [NSString stringWithString:[[tableData objectAtIndex:indexPath.row]objectForKey:#"cellSubtitle"]];
View.urlString = [[NSString alloc] initWithFormat:#"http://%#",urltoPass];
View.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:View animated:YES completion:nil];
}
When you make a controller in a storyboard, you need to get an instance of that view controller by using instantiateViewControllerWithIdentifier:, not by using alloc init.
WebViewController *View = [self.storyboard instantiateViewControllerWithIdentifier:#"WebView"];
In the storyboard, you need to give the controller the identifier "WebView".

How to select and save multiple values from tables rows

here i have made a table class in which i have a list of 120 words, now i have to select minimum ten rows of the table for further precision.. please any one can guide me that how can i select more than 10 rows from table and save these value in specific array or somewhere else.. please help me out of it.
#implementation tableview
NSArray *myArray ;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
myArray = [NSArray arrayWithObjects:
#"ad (a-d)",.......,Nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [myArray count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (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];
}
cell.textLabel.text = [myArray objectAtIndex:indexPath.row]; //=#"ASDF" works.
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
[self.navigationController pushViewController:detailViewController animated:YES];
}
#end
For multiple cell selection in your table add this code inside didSelectRowAtIndexPath: method. For saving selection values, create an iVar NSMutableArray and add the newly selected object inside didSelectRowAtIndexPath:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)path {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:path];
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
}
One quick idea that come into mind is, as soon as you select a row/cell, save the values in a collection object (array, dictionary), and keep on adding.
Delete from the collection if you deselect the row/cell.

Changing cell content in UITableView when tapped

I'm building a app which has a table view. But I want this to be a table view which expands the cell when you tap on it and close when you tap a second time.
But I was wondering if the following is possible. When the cell isn't selected you only see a picture, title and the beginning of the text. But as soon as the cell is selected, it will expand and show even more subviews, i.e. image views.
Is this possible? For instance, to hide a subview in the cell, and as soon a it is tapped it's visible and aligned the right way? And of course, how do i do that?
Thnx!!!
I did something similar quite a few time ago. You'll find the code at github.
Note that it is very rough, as it where my beginning iPhone days, i.e. properties are missing.
.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource> {
NSIndexPath *selectedIndexPath;
NSDictionary *articles;
}
#end
.m
#import "FirstViewController.h"
#implementation FirstViewController
- (void)viewDidLoad {
[super viewDidLoad];
selectedIndexPath = nil;
articles = [[NSDictionary dictionaryWithObject:[NSArray arrayWithObjects:#"one", #"two", #"three",
#"four", #"five", #"six",
#"seven", #"eight", #"nine",
#"ten", #"eleven", nil]
forKey:#"title"] retain];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[selectedIndexPath release];
[articles release];
[super dealloc];
}
- (int)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[articles allKeys] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [[articles allKeys] objectAtIndex : section];
}
- (int)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
{
id key = [[articles allKeys] objectAtIndex:section];
return [[articles objectForKey : key] count];
}
- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ((selectedIndexPath != nil) && (selectedIndexPath.row == indexPath.row))
return 80.0;
return 40.0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * MyIdentifier = #"MyIdentifier";
UITableViewCell * cell = [self.tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease];
}
id key = [[articles allKeys] objectAtIndex:indexPath.section];
cell.textLabel.text = [[articles objectForKey:key] objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (selectedIndexPath == indexPath) {
selectedIndexPath = nil;
} else {
selectedIndexPath = indexPath;
}
[self.tableView deselectRowAtIndexPath : indexPath animated : NO];
[tableView beginUpdates];
[tableView endUpdates];
}
#end
Yes, I do this in the app I'm working on now.
You need to keep track of the state that a cell is in, either open or closed. If only 1 cell can be open at a time, you can do this by just keeping a reference to the current indexPath. If multiple cells can be open at the same time, you'll need an array of booleans, which tracks if each one is open or closed.
In heightForRowAtIndexPath, just return the correct height based on if the row is open or closed.
In cellForRowAtIndexPath, if the row is closed, hide all the content that shouldn't be visible when it's closed. The views can still be there, but they should be set to hidden = YES.
Finally, in didSelectRowAtIndexPath, set the given index path to open if it was closed, and closed if it was open, then reload the cell with [tableView reloadRowsAtIndexPaths:]. If you are only allowing 1 at a time to be open, then just set your current open index path to the one that was selected, and reload both the one that was selected as well as the one that had been previously open.

Resources