I have a textfield and a tableview. User may select textfield data from tableview or any other data.but after entering user own data my tableview must disappear.how can i achieve this.if i use resign first responder did select rowmethod is not working in tableview.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
txtcity.text = selectedCell.textLabel.text;
}
-(void)hideKeyboard //this is my gesture recogniser method
{
autocompletetableview.hidden=true;//if i didn't use this statement it enter into didselectrow method
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
autocompleteTableView.hidden=YES;
if( textField == txtcity)
{
autocompleteTableView.hidden = NO;
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];// this method loads data into my tableview
return YES;
}
}
(BOOL)textFieldShouldEndEditing:(UITextField *)textField
{
if([txtcity.text isEqualToString:#""])
{
autocompleteTableView.hidden=YES;
return YES;
}
else
autocompleteTableView.hidden=NO;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
return arr2.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier] autorelease];
}
cell.textLabel.text = [[arr2 objectAtIndex:indexPath.row]objectForKey:#"Name"];
cell.textLabel.font=[UIFont boldSystemFontOfSize:12];
cell.textLabel.numberOfLines=0;
return cell;
}
if i use like this if i select row it doesn't enter into did select row at index path method. help me
i am not getting where i have to use resignfirstresponder
resignFirstResponder is used to dismiss the first responder ( keyboard in the case of UITextField). If you want the tableview to disappear set the hidden property to true or remove the tableview from the view hierarchy.
i.e;
[tableView setHidden:YES]
or
[tableView removeFromSuperview];
UPDATE:
If using gesture recognizer for checking on the tap on parent view, you can do the following so that the gesture method is not fired unnecessarily.
I'm assuming you are writing all this code in the view controller for the whole thing.
UITapGestureRecognizer *tapGe = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(hideKeyboard)];
tapGe.numberOfTapsRequired = 1;
tapGe.delegate =self;
[self.view addGestureRecognizer:tapGe]
Then implement the following method in the view controller (Make it conform to UIGestureRecognizerDelegate protocol):
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
If(touch.view==self.view){
return YES; //If its the main view accept the touch
}else{
return NO; //Otherwise(say tableview) don't consume the touch.
}
}
I think It's useful to you.I have used custom cell and I have give my working code here.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [mainDetaileArray count];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 115;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray* views = [[NSBundle mainBundle] loadNibNamed:#"ProductMerchantCell" owner:nil options:nil];
for (UIView *view in views)
{
if([view isKindOfClass:[UITableViewCell class]])
{
cell = (ProductMerchantCell*)view;
//cell.img=#"date.png";
}
}
}
cell.selectionStyle=UITableViewCellSelectionStyleNone;
txtfield = [[UITextField alloc]initWithFrame:CGRectMake(104, 36, 58, 31)];
txtfield.textColor = [UIColor colorWithRed:56.0f/255.0f green:84.0f/255.0f blue:135.0f/255.0f alpha:1.0f];
txtfield.delegate = self;
txtfield.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
txtfield.returnKeyType = UIReturnKeyDone;
indexVal = indexPath.row;
[txtfield setBorderStyle:UITextBorderStyleRoundedRect];
txtfield.textAlignment = UITextAlignmentCenter;
txtfield.text = [quantity_array objectAtIndex:indexPath.row];
// NSLog(#" txtfield.text %#", txtfield.text);
[txtfield setTag:indexPath.row];
[txtfield setAutocapitalizationType:UITextAutocapitalizationTypeWords];
NSString *total_str_price1=[[mainDetaileArray objectAtIndex:indexPath.row]valueForKey:#"total_product_price"];
cell.availbl_pro_lbl.text=[NSString stringWithFormat:#"Total : %#%#",add_currnce_str,total_str_price1];
cell.title_pro_lbl.text=[[mainDetaileArray objectAtIndex:indexPath.row]valueForKey:#"product_title"];
str_price=[[mainDetaileArray objectAtIndex:indexPath.row]valueForKey:#"product_price"];
cell.price_Pro_lbl.text=[NSString stringWithFormat:#"Price : %#%#",add_currnce_str,str_price];
[cell.contentView addSubview:txtfield];
return cell;
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
addtoValue = textField.text;
[quantity_array replaceObjectAtIndex:textField.tag withObject:textField.text];
// NSLog(#"quantity_array %#",quantity_array);
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
[textField resignFirstResponder];
[cell.Quantity_txt resignFirstResponder];
return YES;
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
[cell.Quantity_txt resignFirstResponder];
}
Related
I have Reachability class that I adopted from Apple. My problem is implementing my reachability detection in my ListViewController rather than in the ReachabilityAppDelegate shown in Apple. My problems:
I want to link the calling method in the (UITableViewCell *)tableView:(UITableView
*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath and the reachability detection
I am trying to disable my cell if they detect it is not connected and enable the cell if it
is connected
This is coded in viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver: self selector:#selector(reachabilityChanged:) name:kReachabilityChangedNotification object: nil];
The reachabilityChanged as below:
-(void) reachabilityChanged: (NSNotification* )note{
Reachability* curReach = [note object];
NSParameterAssert([curReach isKindOfClass:[Reachability class]]);
[self updateInterfaceWithReachability: curReach];
}
How do I implement my disabling of UITableViewCells in
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
Take note that I have coded this in the above method:
NSInteger row = [indexPath row];
NSString *contentForThisRow = nil;
static NSString *MyIdentifier = #"MyIdentifier";
if (tableView == [[self searchDisplayController] searchResultsTableView]) {
// Sort search results in alphabetical order
NSArray *sorted = [searchResults sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
contentForThisRow = [sorted objectAtIndex:row];
}else {
contentForThisRow = [nameArray objectAtIndex:row];
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier]autorelease];
}
// Set Device names into Cells
cell.textLabel.text = contentForThisRow;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
NSLog(#"Load cell done");
}
you can code like this , add an instance var BOOL _isOffline
in the class and in your updateInterfaceWithReachability: method
- (void)updateInterfaceWithReachability:(Reachability* )curReach
{
if(curReach == XXXXNotReachable)
{
//your code
_isOffline = YES;
}
else
{
_isOffline = NO;
}
[_tableView reloadData];
}
in your -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
you should add your code to deal with the cell , may be
if(_isOffline)
{
cell.userInteractionEnabled = NO;
}
else
{
cell.userInteractionEnabled = YES;
}
I have implemented a UISearchDisplayController in the UITableViewController. The search is working, but the UISearhDisplayController creates a new tableView with a standard cell, and my tableView is using a custom cell. Another problem is that I use a segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
and the cells in searchResultsTableView are not triggering the segue..
How to display the search results with custom cell and segue working?
This is the codes:
...
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView){
return [nameFilteredObj count];
} else {
return [sortedObj count];
}}
- (CustomCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"customCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [[sortedObj objectAtIndex:indexPath.row] valueForKey:#"Name"];
} else {
cell.nameLabel.text = [[sortedObj objectAtIndex:indexPath.row] valueForKey:#"Name"];
cell.countryLabel.text = [[sortedObj objectAtIndex:indexPath.row] valueForKey:#"Country"];
cell.bottleImageView.image = [UIImage imageNamed:[[sortedObj objectAtIndex:indexPath.row] valueForKey:#"Image"]];
}
return cell;
}
//The codes for filtering the results and update of searchResultsTableView (not necessary for this question I think):
- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
[nameFilteredObj removeAllObjects];
for(NSDictionary *obj in sortedObj)
{
NSString *objName = [obj objectForKey:#"Name"];
NSRange range = [objName rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (range.location != NSNotFound) {
[nameFilteredObj addObject:obj];
}}}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];
return YES;}
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption
{
[self filterContentForSearchText:[self.searchDisplayController.searchBar text] scope:
[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:searchOption]];
return NO;}
...
I'm using Storyboard as interface.
Actually very easy to do, but I found many complicated half-working solutions on the way. Use this easy piece and SearchResultsTableView is GONE:
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
...
self.searchDisplayController.searchResultsTableView.hidden=YES;
return YES;
}
I'm new to developing iOS applications and Objective C itself, so I have a probably very simple question.
Currently I have the following method that is called from a ToolBar Button click. The method is designed to create a table view in the frame variable fr.
- (IBAction)addGolfer:(id)sender {
CGRect fr = CGRectMake(101, 45, 100, 416);
UITableView *tabrleView = [[UITableView alloc]
initWithFrame:fr
style:UITableViewStylePlain];
tabrleView.autoresizingMask =
UIViewAutoresizingFlexibleHeight |
UIViewAutoresizingFlexibleWidth;
tabrleView.delegate = self;
tabrleView.dataSource = self;
[tabrleView reloadData];
self.view = tableView;
}
The result of calling this method is not what I expect. Instead of creating the Table View in the frame "fr", the table view fills the entire screen.
Again I'm totally new and would a appreciate any answers and any suggestions. Thanks!
When you set dataSource and delegate properties for your UITableView, it means, you have to write at least this methods for dataSource:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
If you wouldn't do this, it will be crash. Summary you'll get this (this code may contain syntax or logic errors - I wrote it in notepad):
#interface YourViewController : UIViewController <UITableViewDataSource, UITableViewDelegate> {
UITableView *firstTableView;
UITableView *secondTableView;
}
#end
//
#implementation YourViewController
#pragma mark - Objects Processing
- (void)addGolfer:(UIBarButtonItem *)sender {
if (secondTableView) {
[secondTableView removeFromSuperView];
secondTableView = nil;
}
secondTableView = [[UITableView alloc] initWithFrame:CGRectMake(101, 45, 100, 416)];
secondTableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
secondTableView.delegate = self;
tabrleView.dataSource = self;
[self.view addSubview:secondTableView];
}
#pragma mark - TableView DataSource Implementation
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (tableView == firstTableView) { // your tableView you had before
return 20; // or other number, that you want
}
else if (tableView == secondTableView) {
return 15; // or other number, that you want
}
}
- (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.backgroundView = [[UIView alloc] init];
[cell.backgroundView setBackgroundColor:[UIColor clearColor]];
[[[cell contentView] subviews] makeObjectsPerformSelector:#selector(removeFromSuperview)];
if (tableView == firstTableView) { // your tableView you had before
// ...
}
else if (tableView == secondTableView) {
cell.titleLabel.text = [NSString stringWithFormat:#"Cell %d", indexPath.row + 1];
}
return cell;
}
#end
Step 1: Add delegate UITableViewDataSource,UITableViewDelegate
#interface viewController: UIViewController<UITableViewDataSource,UITableViewDelegate>
{
UITableView *tableView;
}
Step 2:
-(void)viewDidLoad
{
tableView=[[UITableView alloc]init];
tableView.frame = CGRectMake(10,30,320,400);
tableView.dataSource=self;
tableView.delegate=self;
tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
[tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"Cell"];
[tableView reloadData];
[self.view addSubview:tableView];
}
Step 3: Properties for tableview (rows & column)
//-- For no of rows in table
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
//-- Table header height if needed
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 50;
}
//-- Assign data to cells
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath] ;
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.textLabel.text=[your_array objectAtIndex:indexPath.row]; ***(or)*** cell.textLabel.text = #"Hello";
return cell;
}
//-- Operation when touch cells
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Your custom operation
}
Instead of setting the view of the UIViewController, add the tableView as a subview.
Instead of:
self.view = tableView;
Do this:
[self.view addSubview:tableView];
This will properly respect the frame that you set.
I have several fields, lets say 5 for now. I would like to press the return/next key and aloud the user to skip from one to the other to enter data in each. I have a UITableViewCell
// Customize the appearance of table view cells.
- (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] autorelease];
UITextField *FirstField = [[UITextField alloc] initWithFrame:CGRectMake(10, 10, 130, 25)];
FirstField.delegate = self;
FirstField.tag = indexPath.row;
[cell.contentView addSubview:FirstField];
FirstField.returnKeyType = UIReturnKeyNext;
[FirstField release];
}
// Configure the cell...
return cell;
}
I am capturing every time the user presses the return/next key with the following:
// Handle any actions, after the return/next/done button is pressed
- (BOOL)textFieldShouldReturn:(UITextField *)textfield
But even if I know what cell/position/field, I am in, how do I tell the program focus on the next one? I know I have to use becomeFirstResponder, once I have the info.
You can do it by getting nextField using current tag
and make that Field as first responder.
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
int previouTag = textField.tag;
if (previouTag<=numberOfRows) {
UITextField *tempField=(UITextField *)[self.view viewWithTag:previouTag+1];
[tempField becomeFirstResponder];
}
}
`
-(BOOL)textFieldShouldReturn:(UITextField *)textField
{
BOOL finedNext = NO;
int viewIndex = [self.mainScroll.subviews indexOfObject:textField];
for (int i = viewIndex+1; i < self.mainScroll.subviews.count; i++) {
if (!finedNext) {
UIView *view = [self.mainScroll.subviews objectAtIndex:i];
if ([view isKindOfClass:[UITextField class]]) {
finedNext = YES;
[view becomeFirstResponder];
}
}
}
return YES;
}
`
I am trying create an accordion type of uitableviewcell that, when the user selects the cell, it expands to display a detailed info view inline similar to how the digg app works. I initially tried replacing the current tablecell with a customcell in cellForRowAtIndex, however the animation looks a bit choppy as you can see the cell being replaced and overall the effect doesn't work too well.
If you look at the digg app and others who have done this it seems that they aren't replacing the current cell but instead perhaps adding a subview to the cell? The original cell however doesn't seem to animate at all and only the new view accordions into the table.
Does anyone have any ideas how to accomplish a similar effect?
I have made some progress using neha's method below and while the cell is animating the correct way it is wreaking havoc with the other cells in the table. What I have done is subclassed UITableViewCell with a custom class which contains an instance of a UIView which actually draws the view which I then add to the table cell's contentview.
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
if (selected) {
[self expandCell];
}
}
-(void)expandCell {
self.contentView.frame = CGRectMake(0.0, 0.0, self.contentView.bounds.size.width, 110);
}
Here are all the table delegate methods I am using:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
if (isSearching && indexPath.row == selectedIndex) {
static NSString *CellIdentifier = #"SearchCell";
CustomTableCell *cell = (CustomTableCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];
UILabel *theText = [[UILabel alloc] initWithFrame:CGRectMake(10.0, 10.0, cell.contentView.bounds.size.width -20, 22.0)];
theText.text = #"Title Text";
[cell.contentView addSubview:theText];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10.0, 10 + 46.0, cell.contentView.bounds.size.width - 20, 40.0)];
textField.borderStyle = UITextBorderStyleLine;
[cell.contentView addSubview:textField];
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0, 88.0, cell.contentView.bounds.size.width - 20, 22.0)];
testLabel.text = [NSString stringWithFormat:#"Some text here"];
[cell.contentView addSubview:testLabel];
[theText release];
[textField release];
[testLabel release];
return cell;
} else {
static NSString *CellIdentifier = #"Cell";
CustomTableCell *cell = (CustomTableCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
[cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:NO];
selectedIndex = indexPath.row;
isSearching = YES;
[tableView beginUpdates];
[tableView endUpdates];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (isSearching && indexPath.row == selectedIndex) {
return 110;
}
return rowHeight;
}
It seems now that the cell is expanding but not actually being refreshed so the labels, and textfield aren't being shown. They do however show up when I scroll the cell off and on the screen.
Any ideas?
The Apple way to do is quite simple.
First, you'll need to save the selected indexPath row:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedRowIndex = [indexPath retain];
[tableView beginUpdates];
[tableView endUpdates];
}
I'll explain the begin/end updated part later.
Then, when you have the currently selected index, you can tell the tableView that it should give that row more space.
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
//check if the index actually exists
if(selectedRowIndex && indexPath.row == selectedRowIndex.row) {
return 100;
}
return 44;
}
This will return height 100 for the selected cell.
Now we can go back to the begin/end updates. That block triggers the reload of all tableView geometry. Moreover, that block is animated, which eventually gives the impressions of the row expanding.
Pawel's beginUpdates/endUpdates trick is good, and I often use it. But in this case you simply need to reload the rows that are changing state, ensuring that you correctly reload them with the desired cell type, and that you return the correct new cell height.
Here is a complete working implementation of what I think you're trying to accomplish:
.h:
#import <UIKit/UIKit.h>
#interface ExpandingTableViewController : UITableViewController
{
}
#property (retain) NSIndexPath* selectedIndexPath;
#end
.m:
#implementation ExpandingTableViewController
#synthesize selectedIndexPath;
- (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 10;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier1 = #"Cell1";
static NSString *CellIdentifier2 = #"Cell2";
UITableViewCell *cell;
NSIndexPath* indexPathSelected = self.selectedIndexPath;
if ( nil == indexPathSelected || [indexPathSelected compare: indexPath] != NSOrderedSame )
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat: #"cell %d", indexPath.row];
}
else
{
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier2] autorelease];
}
cell.textLabel.text = [NSString stringWithFormat: #"cell %d", indexPath.row];
cell.detailTextLabel.text = [NSString stringWithFormat: #"(expanded!)", indexPath.row];
}
return cell;
}
#pragma mark -
#pragma mark Table view delegate
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ( self.selectedIndexPath != nil && [self.selectedIndexPath compare: indexPath] == NSOrderedSame )
{
return tableView.rowHeight * 2;
}
return tableView.rowHeight;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray* toReload = [NSArray arrayWithObjects: indexPath, self.selectedIndexPath, nil];
self.selectedIndexPath = indexPath;
[tableView reloadRowsAtIndexPaths: toReload withRowAnimation: UITableViewRowAnimationMiddle];
}
#pragma mark -
#pragma mark Memory management
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
}
- (void)dealloc {
[super dealloc];
}
#end
If you don't want to reload the cell (you want to keep your existing cell and just change the size, and likely add/remove some subviews), then simply do the beginUpdates/endUpdates trick in didSelectRowAtIndexPath:, and call some method on your cell to incite the layout change. beginUpdates/endUpdates will prompt the tableView to re-query the heights for each cell - so be sure to return the correct value.
Create a class that subclasses UITableviewcell in your project. Create this class' nib and set its parent to be the class in your project with tableview and override its -
(void)setSelected:(BOOL)selected animated:(BOOL)animated
Write methods contractCell() and expandCell() in this class, and provide the height of the cells you want in expandCell method. Call this methods appropriately based on some flags set to identify wheather the cell is in expanded state or contracted state. Use your tableview's
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
method to handle selection of cells.
Replace your cellForRowAtIndexPath function with this one.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath {
if (isSearching && indexPath.row == selectedIndex) {
static NSString *CellIdentifier = #"SearchCell";
CustomTableCell *cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];
UILabel *theText = [[UILabel alloc] initWithFrame:CGRectMake(10.0,
10.0, cell.contentView.bounds.size.width
-20, 22.0)];
theText.text = #"Title Text";
[cell.contentView addSubview:theText];
UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(10.0, 10 +
46.0, cell.contentView.bounds.size.width - 20, 40.0)];
textField.borderStyle = UITextBorderStyleLine;
[cell.contentView addSubview:textField];
UILabel *testLabel = [[UILabel alloc] initWithFrame:CGRectMake(5.0,
88.0, cell.contentView.bounds.size.width - 20, 22.0)];
testLabel.text = [NSString stringWithFormat:#"Some text here"];
[cell.contentView addSubview:testLabel];
[theText release];
[textField release];
[testLabel release];
return cell;
} else {
static NSString *CellIdentifier = #"Cell";
CustomTableCell *cell = [[[CustomTableCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
[cell setCustomTitle:[timeZoneNames objectAtIndex:indexPath.row] detail:[timeZoneNames objectAtIndex:indexPath.row]];
return cell;
}
}
create array wof dictionary which have a key Select_sts which is 0 in start when click its change 1
accourding u change table
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
customView = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 320.0, 40.0)];
UILabel * headerLabel = [[UILabel alloc] initWithFrame:CGRectZero];
headerLabel.backgroundColor = [UIColor clearColor];
headerLabel.opaque = NO;
headerLabel.textColor = [UIColor blackColor];
headerLabel.highlightedTextColor = [UIColor whiteColor];
headerLabel.font = [UIFont boldSystemFontOfSize:16];
headerLabel.frame = CGRectMake(5.0, 10.0, 300.0, 20.0);
headerLabel.text=[NSString stringWithFormat: #"PNR %#",[[record objectAtIndex:section] objectForKey:#"number"]];
customView.backgroundColor=[UIColor whiteColor];
btn_openClose.tag=section+10000;
btn_openClose.backgroundColor=[UIColor clearColor];
// [btn_openClose setImage:[UIImage imageNamed:#"down_arrow.png"] forState:UIControlStateNormal];
[btn_openClose addTarget:self action:#selector(collapseExpandButtonTap:) forControlEvents:UIControlEventTouchUpInside];
[customView addSubview:btn_openClose];
}
- (void) collapseExpandButtonTap:(id) sender{
int indexNo=[sender tag]-10000;
// NSLog(#"total_record %#",[total_record objectAtIndex:indexNo]);
NSMutableDictionary *mutDictionary = [[total_record objectAtIndex:indexNo] mutableCopy];
if([[mutDictionary objectForKey:#"Select_sts"] integerValue]==0)
[mutDictionary setObject:[NSNumber numberWithInt:1] forKey:#"√"];
else
[mutDictionary setObject:[NSNumber numberWithInt:0] forKey:#"Select_sts"];
[total_record replaceObjectAtIndex:indexNo withObject:mutDictionary];
// [table_view beginUpdates];
// [table_view reloadData];
// [table_view endUpdates];
NSMutableIndexSet *indetsetToUpdate = [[NSMutableIndexSet alloc]init];
[indetsetToUpdate addIndex:indexNo]; // [indetsetToUpdate addIndex:<#(NSUInteger)#>]
// You can add multiple indexes(sections) here.
[table_view reloadSections:indetsetToUpdate withRowAnimation:UITableViewRowAnimationFade];
}