How to show Updated values of UITableViewCell from another method ? - ios

I declared globally
NSIndexPath *selectedIndexPath;
and here is my didselectmethod
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath
{
UIAlertView *loAlert = [[UIAlertView alloc]initWithTitle:#"Are you sure you want to redeem?" message:nil delegate:self cancelButtonTitle:#"Yes" otherButtonTitles:#"No", nil];
loAlert.tag = 10;
[loAlert show];
selectedIndexPath = indexPath;
}
After selecting row i am showing alert
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex: (NSInteger)buttonIndex
{
if(alertView.tag == 10)
{
if(buttonIndex == 0)
{
[self redeemOfferService];
}
}
}
Then calling redeemOfferService, in this method i am facing problem
- (void)redeemOfferService
{
OffersBoughtCellTableViewCell * selectedCell1 = [offersTableView cellForRowAtIndexPath:selectedIndexPath];
NSLog(#"%# ************", selectedCell1.quantity.text);
// for e.g. selected cell's quantity is 0 (here i can see selected cell quantity)
i want to change and update here as follow
selectedCell1.quantity.text = #"Quantity : 5";
// after this i can see quantity in my cell is 5 but
when i scroll values are again showing from
cellForRowAtIndexPath i want to show updated value on cell,
how to do this ?
}
For more details here is my cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
OffersBoughtCellTableViewCell *cell = (OffersBoughtCellTableViewCell *)
[tableView dequeueReusableCellWithIdentifier:#"offersCell" forIndexPath:indexPath];
OfferDetail * offerDetailObj=[[OfferDetail alloc]init];
// OfferDetail, OffersBoughtDetails are NSObject class
// #property (nonatomic, strong) OfferDetail *offerObj;& OffersBoughtDetails * selectedOfferBoughtObj;
// and #property (nonatomic, strong) NSArray *offersBought;
offerDetailObj=[self.listOfOffers objectAtIndex:indexPath.row];
OffersBoughtDetails * offerBoughtObj=[self.offerObj.offersBought objectAtIndex:indexPath.row];
selectedOfferBoughtObj=offerBoughtObj;
cell.quantity.text=[NSString stringWithFormat:#"Quantity : %#",offerBoughtObj.quantity];
}

The problem is that when you scroll to your changed cell again, - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath get invoked, but your data would not change,cell.quantity.text=[NSString stringWithFormat:#"Quantity : %#",offerBoughtObj.quantity];, so your cell's quantity still shows what your data model offerBoughtObj is.
Since iOS uses MVC, a solution is you change your data model, and then reflect your model changes to your view.
- (void)redeemOfferService {
OffersBoughtDetails * offerBoughtObj=[self.offerObj.offersBought objectAtIndex:selectedIndexPath];
// change offerBoughtObj to the value you want
offerBoughtObj.quantity = whateveryoulike;
// reload your tableview
[tablview reloadRowsAtIndexPaths:#[selectedIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

As far As I understand your problem after selecting a Cell You want to remove that cell from UITableView.
To do this put all your UITable data in NSMutableArray
And In your - (void)redeemOfferService method after doing all task
just remove that selected object like:
[dataArray removeObject:#"selectedObject"];
And reload the table Data
[tableView reloadData];

You have to update the source of the table, the offerDetailObj in your case, so in - (void)redeemOfferService methods, fetch the data from the array and get the selected object, update it's value and save it again to your array. I think this should work:
- (void)redeemOfferService
{
OffersBoughtCellTableViewCell * selectedCell1 = [offersTableView cellForRowAtIndexPath:selectedIndexPath];
NSLog(#"%# ************", selectedCell1.quantity.text);
// for e.g. selected cell's quantity is 0 (here i can see selected cell quantity)
//i want to change and update here as follow
selectedCell1.quantity.text = #"Quantity : 5";
//Update your source array to the correct value
offerDetailObj=[self.listOfOffers objectAtIndex:indexPath.row];
OffersBoughtDetails * offerBoughtObj=[self.offerDetailObj.offersBought objectAtIndex:indexPath.row];
OffersBoughtDetails.quantity = 5;
[offerDetailObj replaceObjectAtIndex:indexPath.row withObject:offerBoughtObj];
self.listOfOffers replaceObjectAtIndex:indexPath.row withObject:offerDetailObj];
}
Your Array should be mutable so you can add/remove/replace object from it, means that your listOfOffers and offersBought should be NSMutableArray.

I think in your alertViewDelegate method you should set selectetdIndexPath to nil if the user selects NO
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex: (NSInteger)buttonIndex
{
if(alertView.tag == 10)
{
if(buttonIndex == 0)
{
[self redeemOfferService];
}
else
selectedIndexPath = nil;
}
}
and in your redeemOffService you should reload cell
- (void)redeemOfferService
{
OffersBoughtCellTableViewCell * selectedCell1 = [offersTableView cellForRowAtIndexPath:selectedIndexPath];
NSLog(#"%# ************", selectedCell1.quantity.text);
// for e.g. selected cell's quantity is 0 (here i can see selected cell quantity)
i want to change and update here as follow
selectedCell1.quantity.text = #"Quantity : 5";
[self.tableView reloadRowsAtIndexPaths:#[selectedIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
selectedIndexPath = nil;
}
Hope this helps :D

Related

iOS : How to save selected row of tableview even I refresh tableview?

Using some API, I am displaying data in table view format.
A) In that when API is called first time we will get 10 user details, so at first time we can see 10 rows in tableview. When we scroll down i.e after 10 rows, a new API called for nextPageURL i.e page 2 and it contains gain 10 user details. Again when you reach 20 row after again nextPageURL i.e page 3 API will call and again 10 records will get in JSON and again it will displayed in tableview. (This is working fine. There is no issue while getting data and displaying in data) This is the working flow my tableview in my project.
B) Here I am using UILongPressGestureRecognizer for selecting rows of tableview. Using UILongPressGestureRecognizer I can able to select multiple rows. (This is also working fine)
C) Code used for it, selecting and deselecting tableview row
#interface InboxViewController ()
{
NSMutableArray *selectedArray;
NSString *selectedIDs;
}
#property (strong,nonatomic) NSIndexPath *selectedPath;
- (void)viewDidLoad
{
selectedArray = [[NSMutableArray alloc] init];
self.tableView.allowsMultipleSelectionDuringEditing = true;
UILongPressGestureRecognizer *lpGesture = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:#selector(EditTableView:)];
[lpGesture setMinimumPressDuration:1];
[self.tableView addGestureRecognizer:lpGesture];
[self reload]; // for getting data
}
-(void)reload
{
// API sample
NSString * url= [NSString stringWithFormat:#"%#api/v2/get-userDetails?token=%#&api=%#&show=%#&departments=%#",[userDefaults objectForKey:#"baseURL"],[userDefaults objectForKey:#"token"],apiValue,showInbox,Alldeparatments];
NSLog(#"URL is : %#",url);
// here get JSON (First 10 user details data)
}
-(void)EditTableView:(UIGestureRecognizer*)gesture{
[self.tableView setEditing:YES animated:YES];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.currentPage == self.totalPages
|| self.totalTickets == _mutableArray.count) {
return _mutableArray.count;
}
return _mutableArray.count + 1;
}
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.row == [_mutableArray count] - 1 ) {
NSLog(#"nextURL111 %#",_nextPageUrl);
if (( ![_nextPageUrl isEqual:[NSNull null]] ) && ( [_nextPageUrl length] != 0 )) {
[self loadMore]; // this method is called for getting next data i.e getting next 10 user details
}
else{
NSLog (#"ALL Caught UP");
}
}
this is for first API call and here I will get 10 user details and I am displaying in tableview.
For getting next user details following method is called
-(void)loadMore
{
// next page API called here
}
for selecting row I am using following,
-(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 3;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath{
return YES;
}
Selecting and deselecting rows
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
self.selectedPath = indexPath;
if ([tableView isEditing]) {
// [selectedArray addObject:[_mutableArray objectAtIndex:indexPath.row]];
[selectedArray addObject:[[_mutableArray objectAtIndex:indexPath.row] valueForKey:#"id"]];
count1=(int)[selectedArray count];
NSLog(#"Selected count is :%i",count1);
NSLog(#"Slected Array Id : %#",selectedArray);
selectedIDs = [selectedArray componentsJoinedByString:#","];
NSLog(#"Slected Ticket Id are : %#",selectedIDs);
}else{
// goes to next detail view
}
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedPath = indexPath;
// [selectedArray removeObject:[_mutableArray objectAtIndex:indexPath.row]];
[selectedArray removeObject:[[_mutableArray objectAtIndex:indexPath.row] valueForKey:#"id"]];
count1=(int)[selectedArray count];
NSLog(#"Selected count is :%i",count1);
NSLog(#"Slected Id : %#",selectedArray);
selectedIDs = [selectedArray componentsJoinedByString:#","];
NSLog(#"Slected Ticket Id are : %#",selectedIDs);
if (!selectedArray.count) {
[self.tableView setEditing:NO animated:YES];
}
}
My Problem/Issue -
I am selecting row of tableview using UILongPressGestureRecognizer, up to 10 rows (it is in front end) and in background in one array its id is storing. If you select some rows, its row id will add in selectedArray if you deselect row it will remove object from selectedArray
Now suppose I selected 5 tickets and suppose when I scroll down (after 10 rows) new API will call, and next 10 userdetails will display, but this time whatever selected rows are vanishing (selected rows are showing unselected) but still in background there id is stored.
What I want is that, when I select some rows even I scroll down and goes to any page, that selected arrow will not vanish and that that selected row is stored in selectedArray object
If you're using multiple selection, you can add this method to your ViewController and call it whenever you need to call [tableView reloadData] to preserve the selection.
- (void)reloadTableView
{
NSArray *indexPaths = [self.tableView indexPathsForSelectedRows];
[self.tableView reloadData];
for (NSIndexPath *path in indexPaths) {
[self.tableView selectRowAtIndexPath:path animated:NO scrollPosition:UITableViewScrollPositionNone];
}
}
Referred from save selected row in UITableView after reloadData

Add objects into array from UITableViewCell

Here i need to implement add objects into array for multiple row selections,here is my code
BOOL selectedRow
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath{
if(selectedRow){
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
cellText = selectedCell.textLabel.text;
NSLog(#"Airline cellTextC = %#",cellText);
if ([cellText isEqualToString:NameString]) {
NSLog(#"Selected NameString Index = %#",indexes);
[nameArray addObject:indexes];
}else{
NSLog(#"Unknown Selected Name");
}
}
NSLog(#"Total Names = %#",nameArray.description);
}
the above code one section and multiple rows is there ,if am selected a row name string should be add to the Array .It's working fine for only while am selecting one row.But i need add objects from multiple row selections.Can you please suggest me thanks .
You probably want to update the data source of the Table View, and let the Table View Data source methods to update the Table View for you.
Check if this can solve your problem:
[tableView setAllowsMultipleSelection:YES];
if you want to select Multiple rows and add objects to your array i suggest to create 2 NSMutableArray the first one contains all data and the other the selected rows data.
#property (strong , nonatomic) NSMutableArray *myalldatatab;
#property (strong , nonatomic) NSMutableArray *selecteddata;
then use didselectrowsatindexpath and didDeselectRowAtIndexPath to change the mark
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone;
}
and you can get indexes of selected rows by calling this line :
NSArray *selectedCells = [self.tableView indexPathsForSelectedRows];
you can now iterate selected cells and add objects like this
for (int i = 0; i < [selectedCells count]; i++)
{
[self.selecteddata addObject: [selectedCells objectAtIndex:i]]
}
Hope it help you :)) happy c0de !!

Unable to refresh UITableView when rows are deleted

I have a UITableView having many rows that contains UITextFields. User enters data to these fields. user can delete or add any rows. When i am trying to delete any row it deletes the correct row from the array(that contains all the cell's reference) but the UITextfield always shows that the last row is deleted.
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _countEmailValues.count ;
}
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"CustomEmailCell";
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (!cell) {
cell = [[LACustomEmailCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.emailTextField.tag = 555;
cell.deleteEmailFieldButton.tag = indexPath.row;
NSLog(#"delete email Field tag %i",cell.deleteEmailFieldButton.tag );
cell.emailTextField.delegate = self;
if ([_countEmailValues count] > 1 )
{
cell.deleteEmailFieldButton.hidden = false;
}
else
{
cell.deleteEmailFieldButton.hidden = true;
}
// Reason why I am adding cell.emailtextfield in this delegate? is should be in addButtonclick but cell.emailtextfield is not
// initialized there. Also adding of only cell will give null for the emailTextField.
// So adding all cells here and then removing duplicates entires and accessing over the app.
[_emailValues addObject:cell.emailTextField];
// Remove Duplicate elements.
NSArray *emailFieldCollection = [_emailValues copy];
NSInteger index = [emailFieldCollection count ] -1;
for (id object in [emailFieldCollection reverseObjectEnumerator])
{
if ([_emailValues indexOfObject:object inRange:NSMakeRange(0, index)] != NSNotFound)
{
[_emailValues removeObjectAtIndex:index];
}
index--;
}
NSLog(#"Row : %i",indexPath.row);
return cell;
}
- (IBAction)deleteEmailClick:(UIButton *)sender
{
NSIndexPath *index = self.emailTableView.indexPathForSelectedRow;
// [self.emailTableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:indexPath.row inSection:0] animated:YES scrollPosition:0];
NSIndexPath *indexPath = [_emailTableView indexPathForSelectedRow];
NSLog(#"Tags %i", sender.tag);
// [self.emailTableView reloadData];
if ([_countEmailValues count] > 0)
{
[ _countEmailValues removeObjectAtIndex:sender.tag];
}
// NSLog(#"array after %#",_countEmailValues);
if ([_countEmailValues count] == 0)
{
// _deleteEmailButton.hidden = true;
_doneButton.hidden = true;
}
NSLog(#"array before %#",_emailValues);
if ([_emailValues count] > 0)
{
[_emailValues removeObjectAtIndex:sender.tag];
}
[self.emailTableView reloadData];
}
The _emailValues gets updated properly but the data in the fields is always getting cleared of the last one.
EX: in the image if i delete "b" the _emailValues gets cleared properly but the ui shows two field having data "a" & "b" . what have i missed here?
pls help.
You are not deleting the cell . In deleteEmailClick add this line
[self.emailTableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationLeft];
Also I would like to point out another way of implementing delete using a block. This will ensure that you always have the correct cell and no need to tag your delete button. This would be cleaner and maintainable. In your custom cell class LACustomEmailCell declare a block property like so
#property (strong, nonatomic) void (^deleteButtonTappedBlock)();
Connect the IBAction of your delete button in the LACustomEmailCell class and from there call this block. I am assuming the name as deleteButtonPressed
- (IBAction)deleteButtonPressed:(id)sender {
self.deleteButtonTappedBlock();
}
Now in -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
You can set the block like this
[cell setDeleteButtonTappedBlock:^(){
//Action to perform when cell is deleted. In your case the code in `deleteEmailClick` will go here.
//In the end delete the cell.
[self.emailTableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}];
i hope this helps

How to create a dynamic size array

What I am trying to achieve:
I have a UITableView and I want to check whether the table was selected or not and keep in an array easy to access the YES or NO values that corresponds to that row so that afterwards i can manipulate the data.
my code as follows
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellLabelText = cell.textLabel.text;
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
cell.accessoryType = UITableViewCellAccessoryNone;
selected[row] = NO;
}
else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
selected[row] = YES;
}
}
As it stands out I can create a BOOL selected[some value] but my problem is that the max index needed for me is unknown as my table size changes constantly. thus setting the max index limits me.
I am new to objective C and I come from a PHP background thus I dont know whether it is possible to create an array that does what i want to do in objective-c.
Otherwise what would be my options within objective-c to have an easy way to easy write/read selected[row] = YES/NO.
I need a way to write YES/NO and link it to the indexpath.row
Use an NSMutableSet and store the NSIndexPath of the selected rows. If you select a row you add the path to the set. If you unselect a row, remove the path from the set.
To see if a row is selected, see if the indexPath is in the set or not.
BTW - this only works if the rows are fixed. If the user can add, remove, or reorder rows then this approach will not work. In such a case you need to store data keys, not index paths.
Create an ivar of type NSMutableSet. Let's call it selectedRows:
selectedRows = [[NSMutableSet alloc] init];
Then in didSelectRow you do:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
BOOL selected = [selectedRows containsObject:indexPath];
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellLabelText = cell.textLabel.text;
if (selected) {
cell.accessoryType = UITableViewCellAccessoryNone;
[selectedRows removeObject:indexPath];
} else {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[selectedRows addObject:indexPath];
}
}
In your cellForRow... method you do something similar:
BOOL selected = [selectedRows containsObject:indexPath];
cell.accessoryType = selected ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
Just use
NSMutableArray *dynamicArray = [NSMutableArray array];
You can add and delete objects from this at will. Just be sure to use the NSNumber wrapper to add primitives:
[dynamicArray addObject:[NSNumber numberWithInt:indexNumber]];
// or
[dynamicArray addObject:#(indexNumber)];
Instead of an array you can use a index set.
#property (nonatomic,strong) NSMutableIndexSet *pickedIndexPaths;
- (void)viewDidLoad
{
_pickedSIndexPaths = [[NSMutableIndexSet alloc] init];
[super viewDidLoad];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//…
if(indexPath.section == 0) {
cell.textLabel.text = self.sports[indexPath.row][#"sport"][#"name"];
if ([_pickedIndexPaths containsIndex:indexPath.row]) {
[cell setAccessoryType:UITableViewCellAccessoryCheckmark];
} else {
[cell setAccessoryType:UITableViewCellAccessoryNone];
}
}
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([_pickedIndexPaths containsIndex:indexPath.row]) {
[_pickedIndexPaths removeIndex:indexPath.row];
} else {
[_pickedIndexPaths addIndex:indexPath.row];
}
[tableView reloadData];
}
}
When what you need is a variable length array of boolean values, you can use CFBitVectorRef. This will consume much less memory than using a Cocoa collection designed for objc object values (provided of course that array has many elements) because it consumes 1 bit for each value, rather than a full pointer which points to an individual dynamically allocated reference counted object.

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