I need idea how to implement this kind of custom UITableViewCell by animating, just like the out-of-the-box feature of UITableViewCell when sliding left or right.
What I've done so far (and is working), is:
Add a button with that circle image.
Toggle visibility of that button.
Toggle highlighted and normal state of the button.
Toggle constraints of the whole views when showing or hiding the radio button in #2.
Reload Data.
I'm thinking that this question might make my implementation cleaner when instead of toggling visibility and constraints of my custom tableViewCell, just slide it or animate it.
EDIT: These radio buttons appear only in a certain mode, like editing mode. So normally, there are no radio buttons in my cells.
You can try this I created Simple Demo.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>
{
NSMutableArray *dataArray;
}
#property (weak, nonatomic) IBOutlet UITableView *mTableView;
// You can toggle the Selection by Means you can show hide the checkboxes
- (IBAction)didTapBringCheckBoxBtn:(id)sender;
#end
View controller.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
dataArray=[[NSMutableArray alloc]init];
[dataArray addObject:#"Apple"];
[dataArray addObject:#"Mango"];
[dataArray addObject:#"Papaya"];
[dataArray addObject:#"Guava"];
[dataArray addObject:#"Pineapple"];
[dataArray addObject:#"Strawberry"];
[dataArray addObject:#"Banana"];
[dataArray addObject:#"Grapes"];
[dataArray addObject:#"Pomegranate"];
[dataArray addObject:#"Green Tea"];
[dataArray addObject:#"Raisin"];
self.mTableView.delegate=(id)self;
self.mTableView.dataSource=(id)self;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Check Box Button Action
- (IBAction)didTapBringCheckBoxBtn:(id)sender {
if(self.mTableView.editing==YES)
{
[self.mTableView setEditing:NO animated:YES];
}else{
[self.mTableView setEditing:YES animated:YES];
}
}
#pragma mark - UITableView DataSource Methods
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [dataArray count];
}
- (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 = [dataArray objectAtIndex:indexPath.row];
return cell;
}
#pragma mark - UITableView Delegate Methods
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 3;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"user selected %#",[dataArray objectAtIndex:indexPath.row]);
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"user de-selected %#",[dataArray objectAtIndex:indexPath.row]);
}
#end
OutPut Will look Like This :
At Start Not showing Checkboxes :
On click Show CheckBox :
You did the harder, you just need to hide your button, here is a similar implementation I did to have a delete button and delete it without a confirmation.
1) Made a subview in content view, and made it bigger than content view with a negative leading space (-42 is the value of the slide offset)
Then put your checkmark button in this hidden space like I did for mine:
Then when you will set editing mode to true, your checkbox will appear with slide animation ;)
Lets consider your data source looks like
NSMutableDictionary *sampleRecord = [[NSMutableDictionary alloc] initWithObjectsAndKeys:#"isSelected",#"true",#"title",#"title text", nil];
records = [[NSMutableArray alloc] init];
[records addObject:[sampleRecord copy]];
[records addObject:[sampleRecord copy]];
[records addObject:[sampleRecord copy]];
And your table delegate/data source methods should be
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return [records count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
//Initialize your cell
//Read the all views from your cell
//Now add the click event to your radio button (UIButton)
[myButton addTarget:self action:#selector(changeRadioState) forControlEvents: UIControlEventTouchUpInside];
return cell;
}
- (IBAction)changeRadioState:(id)sender
{
//Detect the row index fro table where is the button present
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:tableView];
NSIndexPath *indexPath = [tableView indexPathForRowAtPoint:buttonPosition];
//Now get the resource data for clicked row
NSMutableDictionary *record = [records objectAtIndex:indexPath.row];
//Change the selected state images
if ([[records valueForKey:#"isSelected"] isEqualToString:#"true"]) {
[sender setImage:[UIImage imageNamed:#"unSelectStateImage"] forState:UIControlStateNormal];
[record setValue:#"false" forKey:#"isSelected"];
}
else{
[sender setImage:[UIImage imageNamed:#"selectedStateImage"] forState:UIControlStateNormal];
[record setValue:#"true" forKey:#"isSelected"];
}
//Reload entire table
[tableView reloadData];
//Or else you can reload the single row by
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
MGSwipeTableCell is an easy to use UITableViewCell subclass that allows to display swipeable buttons with a variety of transitions.
https://github.com/MortimerGoro/MGSwipeTableCell
Related
I need to recreate a UITableView section on a UIButton click. Here is an example for this.
AND in button click it should be created like this.
But i am not able to implement this .
Please Help.
I am just creating a simple UITableView with a textLabel.
Code For cellForRowAtIndexPath is
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpleTableItem";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];
return cell;
}
Create a integer variable index and property for tableview in .h
#property UITableView *tableView;
Then in -(void)viewDidLoad set index=0;
Now, write a method which is get called when you tap on add button
-(void)newTableView
{
tableView = [UITableView alloc] initWithFrame:CGRectMake(x,y+height*index,width,height)];
//other code related to table
tableView.tag = ++index;
[self.view addSubview:tableView];
}
Use tag in delegate methods
Edit: As you requested to add new section in Table View instead of new table view
You have to first create table view of grouped style
tableView = [UITableView alloc] initWithFrame:(CGRect)frame style:UITableViewStyleGrouped];
Now, When you hit on that add button call a method
-(void)newSection
{
count++;
[tableView reloadData];
}
Then, you have to implement this delegate methods for grouped table view
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
return count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return #"title";
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
//same as your previous code
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
//same as your previous code
}
//
// ViewController.m
// DynamicNewSections
//
// Created by J Pulikkottil on 14/07/15.
// Copyright (c) 2015 J Pulikkottil. All rights reserved.
//
#import "ViewController.h"
#interface ViewController ()
#property(nonatomic) NSMutableArray *arrayData;
#property (strong, nonatomic) IBOutlet UITableView *tableViewTest;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.arrayData = [NSMutableArray array];
//section1
[self addSectionArray];
}
- (IBAction)addSection:(UIButton *)sender {
[self addSectionArray];
[self.tableViewTest reloadData];
}
- (void) addSectionArray{
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"Height",#"label", #"", #"value", nil];
NSArray *arraysection = [NSArray arrayWithObjects:dict, nil];
[self.arrayData addObject:arraysection];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableViewTest.frame.size.width, 45)];
view.backgroundColor = [UIColor yellowColor];
return view;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return [self.arrayData count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [[self.arrayData objectAtIndex:section] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"CellDetails" forIndexPath:indexPath];
NSArray *arraysection = [self.arrayData objectAtIndex:indexPath.section];
NSDictionary *dict = [arraysection objectAtIndex:indexPath.row];
cell.textLabel.text = [dict valueForKey:#"label"];
cell.detailTextLabel.text = [dict valueForKey:#"value"];
return cell;
}
#end
Try this:
Just have a property (e.g. numberOfSections)
Set it to 1 in viewDidLoad
In the numberOfSectionsInTableView: return self.numberOfSections;
In the IBAction of your UIButton add this code:
self.numberOfSections++;
[self.tableView beginUpdates];
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:self.numberOfSections-1]
withRowAnimation:UITableViewRowAnimationBottom];
[self.tableView endUpdates];
So I have been creating a tableviewcontroller that handles my tableview and its tableviewcells..
Here's the code––
ItemsViewController.h
#import <UIKit/UIKit.h>
#import "DetailViewController.h"
#interface ItemsViewController : UITableViewController <UITableViewDataSource, UITableViewDelegate>
-(IBAction)addNewItem:(id)sender;
#end
ItemsViewController.m
#implementation ItemsViewController
-(id) init{
self= [super initWithStyle:UITableViewStyleGrouped];
if (self) {
UINavigationItem *n= [self navigationItem];
[n setTitle:#"Homepwner"];
for (int i=0; i<5; i++) {
[[BNRItemStore sharedStore] createItem];
}
}
return self;
}
- (id)initWithStyle:(UITableViewStyle)style
{
return [self init];
}
- (void)viewDidLoad
{
NSLog(#"ItemsView loaded");
[super viewDidLoad];
UIBarButtonItem *bbi= [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:#selector(addNewItem:)];//Target-Action pair..
self.navigationItem.rightBarButtonItem= bbi;
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
}
-(void)viewWillAppear:(BOOL)animated{
NSLog(#"ItemsView appearing");
[super viewWillAppear:animated];
[[self tableView] reloadData];
}
-(IBAction)addNewItem:(id)sender{
BNRItem *newItem= [[BNRItemStore sharedStore] createItem];
NSLog(#"%d",[[[BNRItemStore sharedStore] allItems] count]);
int newRow = [[[BNRItemStore sharedStore] allItems] indexOfObject:newItem];
NSIndexPath *ip= [NSIndexPath indexPathForRow:newRow inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:ip] withRowAnimation:UITableViewRowAnimationTop];
}
//Row Selection
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
if(indexPath.row<[[BNRItemStore sharedStore] allItems].count){
NSLog(#"Row# %d selected",indexPath.row);
DetailViewController *detailViewController= [[DetailViewController alloc] init];
NSArray *items= [[BNRItemStore sharedStore] allItems];
BNRItem *item= [items objectAtIndex:indexPath.row];
detailViewController.item=item;//BNRItem at the selected indexPath.
//Push it onto the top of the navigation controller's stack
[[self navigationController] pushViewController:detailViewController animated:YES];
}
else{
return;
}
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"Test1");
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//#warning Incomplete method implementation.
// Return the number of rows in the section.
NSLog(#"Current section- %d",section);
return [[[BNRItemStore sharedStore] allItems] count]+1 ;//no. of rows (5)+'No more items' row
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"hello");
// NSLog(#"%#",headerView);
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (!cell) {
cell= [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (indexPath.row<[[BNRItemStore sharedStore] allItems].count) {
[[cell textLabel] setText:[[[[BNRItemStore sharedStore] allItems] objectAt Index:indexPath.row] description]];
}
else if (indexPath.row== [[BNRItemStore sharedStore] allItems].count)
{
[[cell textLabel] setText:#"No more items"];
}
return cell;
}
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
if (self.editing) {
NSLog(#"Editing is on");
self.navigationItem.rightBarButtonItem.enabled=NO;
if (indexPath.row==[[BNRItemStore sharedStore] allItems].count) {
[tableView cellForRowAtIndexPath:indexPath].hidden=YES;
return NO;// Do not make 'No more items' editable.
}
}
else{//When the user is out of editing mode
NSLog(#"editing done");
[self.tableView cellForRowAtIndexPath:indexPath].hidden=NO;
self.navigationItem.rightBarButtonItem.enabled=YES;
}
return YES;
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",NSStringFromSelector(_cmd));
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSLog(#"Deletion is on");
// Delete the row from the data source
NSArray *items= [[BNRItemStore sharedStore] allItems];
BNRItem *p= [items objectAtIndex:[indexPath row]];
[[BNRItemStore sharedStore] removeItem:p];
[tableView deleteRowsAtIndexPaths:#[indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
[[BNRItemStore sharedStore] moveItemAtIndex:fromIndexPath.row toIndex:toIndexPath.row];
}
-(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedIndexPath{
if (proposedIndexPath.row==[[BNRItemStore sharedStore] allItems].count) {// 'No more items' row
return [NSIndexPath indexPathForRow:proposedIndexPath.row-1 inSection:0];
}
return proposedIndexPath;
}
#end
When the editing mode is on i.e when i tap Edit button on the NavBar the Add button grays out and the 'No more items' rows becomes hidden. After exiting Edit mode (by tapping 'Done' button) the Add button becomes selectable and the 'No more items' row unhides.. This is all fine when i perform editing by first entering the Edit mode and then exiting the Edit mode. But when instead of using the above way, i use swipe to delete feature, the view doesn't realize the above functionality (i.e. Ungraying/Re-enabling the Add button once i'm done doing a deletion using the swipe to delete thing. When i swipe across a cell (so as to bring up the delete button on the right side of the cell and graying out the Add button in the process) and choose not to press the 'Delete' button by just retapping on the cell (so that the Delete button goes away) the Add button does not update itself so as to get enabled.. What to do about. Pls carefully examine my code first and give recommendations accordingly..
use this tableView Delegate mathod
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
return UITableViewCellEditingStyleDelete;
}
- (BOOL)tableView:(UITableView *)tableView shouldIndentWhileEditingRowAtIndexPath:(NSIndexPath *)indexPath
{
return NO;
}
Please Utilize the Apple Library- UItableView
I'm developing an iOS app with latest SDK.
I have an UITableView with a lot of rows but I only show five rows. In other words, the user only can see five rows. He/she can scrolls the table, but only five rows are visible.
I want to make selectable the third row. The user only can select the third visible row.
I'm trying to simulate an UIPickerView first, because I'm using Core Data and all the code now works fine with UITableView delegate and, second, I don't know how to customize UIPickerView background and selection area.
How can I make the third visible row the only row selectable?
implement -[id<UITableViewDelegate> tableView:willSelectRowAtIndexPath:] like this:
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *indexPaths = [tableView indexPathsForVisibleRows];
if ([indexPaths objectAtIndex:2] isEqual:indexPath) {
return indexPath;
} else {
return nil;
}
}
More info here
Complete example along with snap to rows (by implementing ScrollView Delegate):
ViewController.h:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (weak, nonatomic) IBOutlet UITableView *myTableView;
#end
ViewController.m:
#import "ViewController.h"
static int kRowHeight = 92;
static int kArrayCount = 20;
#interface ViewController ()
#property (nonatomic, strong) NSMutableArray *tableViewData;
#end
#implementation ViewController
-(void)populateArray {
for (int i=0; i<kArrayCount; i++) {
[self.tableViewData addObject:[NSString stringWithFormat:#"String # %d",i]];
}
[self.myTableView reloadData];
}
#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.tableViewData count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.textLabel.text = [self.tableViewData objectAtIndex:indexPath.row];
// Configure the cell...
return cell;
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
// Standard UIAlert Syntax
UIAlertView *myAlert = [[UIAlertView alloc]
initWithTitle:#"Selected"
message:[NSString stringWithFormat:#"Selected Row %d", indexPath.row]
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
[myAlert show];
}
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSArray *indexPaths = [tableView indexPathsForVisibleRows];
if ([[indexPaths objectAtIndex:2] isEqual:indexPath]) {
return indexPath;
} else {
return nil;
}
}
#pragma mark - ScrollView Delegate Methods (Make rows snap to position top)
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView
withVelocity:(CGPoint)velocity
targetContentOffset:(inout CGPoint *)targetContentOffset {
int cellHeight = kRowHeight;
*targetContentOffset = CGPointMake(targetContentOffset->x,
targetContentOffset->y - (((int)targetContentOffset->y) % cellHeight));
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableViewData = [[NSMutableArray alloc] initWithCapacity:kArrayCount];
[self populateArray];
// Do any additional setup after loading the view, typically from a nib.
}
#end
You can use the array [self.tableView indexPathsForVisibleRows] to find out what indexPaths are visible. In the willSelectRowAtIndexPath method return nil for all but the third element.
To avoid highlighting you can also use this to set
cell.selectionStyle = UITableViewCellSelectionStyleNone;
In the CFRAIP method.
I am trying to create a UITableView application on Xcode 4.2. I just want each cells (ex. Cali) to push a new UIViewController when it's touched.
The issue I'm running into is whenever I press the cell it's not pushing the new view controller.
When I put a break point at the didSelectRowAtIndexPath method, I see 5 threads.
Here's my code:
#import <UIKit/UIKit.h>
#interface Adam : UITableViewController
{
NSMutableArray *states;
}
#end
#import "Adam.h"
#import "ViewController.h"
#implementation Adam
- (void)viewDidLoad
{
[super viewDidLoad];
states = [NSMutableArray arrayWithObjects:
#"cali",
#"ohio",
nil];
// Uncomment the following line to preserve selection between presentations.
// self.clearsSelectionOnViewWillAppear = NO;
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [states count];
}
- (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];
}
UILabel *cellLabel = (UILabel *)[cell viewWithTag:1];
[cellLabel setText:[states objectAtIndex:indexPath.row]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if ([[states objectAtIndex:indexPath.row] isEqual:#"cali"])
{
ViewController *cali = [[ViewController alloc] initWithNibName:#"cali" bundle:nil];
[self.navigationController pushViewController:cali animated:YES];
}
}
#end
First the TableViewCell has a textLabel property so you don't need to create your own label.
cell.textLabel.text= [states objectAtIndex:indexPath.row];
and is there a reason your deselecting the cell?Try deselecting it after you use the indexPath
And try:
if([states objectAtIndex:indexPath.row] isEqualToString:#"cali"]];){
}
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.