Skip to content

Instantly share code, notes, and snippets.

@lamprosg
Last active December 14, 2015 03:29
Show Gist options
  • Select an option

  • Save lamprosg/5021288 to your computer and use it in GitHub Desktop.

Select an option

Save lamprosg/5021288 to your computer and use it in GitHub Desktop.
(iOS) Simple TableView (no navigation)
//Drag a Table View object from the library onto the .xib (it will cover all the screen
//Connect the dataSource and delegate outlets (from the connection inspector)
//of the Table View component to the view controller (File's Owner)
//Use those 2 protocols
@interface TableExampleViewController : UIViewController<UITableViewDelegate, UITableViewDataSource>
//The data themselves
@property (strong, nonatomic) NSArray *colorNames;
@property (strong, nonatomic) IBOutlet UITableView *mainTable;
//For uncheckable cells
@property (nonatomic, retain) NSIndexPath* checkedIndexPath;
@end
#import "tableViewController.h"
@implementation TableExampleViewController
/*********************************************/
//When using storyboards this init gets called by the viewcontroller
- (id)initWithCoder:(NSCoder *)decoder {
self = [super initWithCoder:decoder];
if (self) {
//bla bla
}
return self;
}
/*********************************************/
//When the view loads
- (void)viewDidLoad
{
[super viewDidLoad];
//Set this to allow tableview selectin during editing
self.tableView.allowsSelectionDuringEditing=YES;
//Set the datato the array (our table list)
self.colorNames = [[NSArray alloc] initWithObjects:@"Red", @"Green", @"Blue", @"Indigo", @"Violet", nil];
//*****************
//Adding a refresh control to the tableview
[self.tableView reloadData];
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
refreshControl.tintColor = [UIColor magentaColor];
refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Pull to refresh"];
//Add a function that will be called when refreshing
[refreshControl addTarget:self action:@selector(refreshTable:) forControlEvents:UIControlEventValueChanged];
self.refreshControl = refreshControl;
//*****************
}
//Called when data are refreshed
-(void)refreshTable:(UIRefreshControl*)refreshControl{
//refresh code here (reload table data etc.)
[refreshControl endRefreshing];
[self.tableView reloadData];
}
//When the view unloads
- (void)viewDidUnload
{
// Release any retained subviews of the main view.
// Release memory if we don't need it
self.colorNames = nil;
}
//How may sections do we have in the table.
//If we wanted to use multipe sections we would make an array to hold the objects of the arrays
//that would hold the data for each section.
/***************************************************
Example:
NSMutableArray *dataArray;
dataArray = [[NSMutableArray alloc] init];
NSArray *firstArray = [[NSArray alloc] initWithObjects:@"Item 1", @"Item 2", @"Item 3", nil];
NSDictionary *firstArrayDict = [NSDictionary dictionaryWithObject:firstItemsArray forKey:@"data"];
[dataArray addObject:firstItemsArrayDict];
NSArray *secondArray = [[NSArray alloc] initWithObjects:@"Item 4", @"Item 5", @"Item 6", nil];
NSDictionary *secondArrayDict = [NSDictionary dictionaryWithObject:secondArray forKey:@"data"];
[dataArray addObject:secondArrayDict];
-----
and number of sections would be
return [dataArray count];
****************************************************/
- (NSInteger)numberOfSectionsInTableView:
(UITableView *)tableView
{
// Return the number of sections.
return 1;
/*For multiple sections
return [dataArray count];
*/
}
//If we have sections, set the header titles for each section
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
if(section == 0)
return @"Section 1";
if(section == 1)
return @"Section 2";
}
//For section footers
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
if(section == 1) //2d section
{
return @"This is a footer";
}
else
{
return @"";
}
}
//Called by the Table View to identify how many rows are to be displayed
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [self.colorNames count];
/* For multiple sections
NSDictionary *dictionary = [dataArray objectAtIndex:section];
NSArray *array = [dictionary objectForKey:@"data"];
return [array count];
*/
}
//This is called by table view when it needs to draw a row.
//This method is called n times and value of n is equal to value returned by first method.
//This method is called once for every row
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//Create a cell identifier
static NSString *CellIdentifier = @"Cell";
//Make an attempt to reuse an existing cell that may have scrolled off the screen and is therefore available
//for use as the currently requested cell.
//If no previous cell is available for use then a new one is created using the UITableViewCellStyleDefault style
//Allocate a new table cell
//dequeueReusableCellWithIdentifier: only returns a cell if it has been marked as ready for reuse
//purpose of dequeueReusableCellWithIdentifier is to use less memory
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
//For the default cells
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
//Or if we want to add subtitles to the cell values
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
/*******************************************************/
//If you have a custom cell on a seperate nib with a cell subclass (instead if UITableViewCell class)
//and with a specific indentifier for the cell
UINib *nibCell = [UINib nibWithName:@"SharedCell" bundle:nil];
[self.tableView registerNib:nibCell forCellReuseIdentifier:@"cellNibIdentifier"];
cell = (CustomCell*) [self.tableView dequeueReusableCellWithIdentifier:@"cellNibIdentifier"];
//Note: Cell nib file must contain a single table view cell
//Check http://www.techotopia.com/index.php/Using_Xcode_Storyboards_to_Build_Dynamic_TableViews_with_Prototype_Table_View_Cells
/*******************************************************/
//To add a little arrow on the right of the cell
//Simple arrow
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
//Detailed arrow
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
//To add checkmarks
cell.accessoryType = UITableViewCellAccessoryCheckmark;
}
// Configure the cell.
//Add an image next to the cell value
UIImage *cellImage = [UIImage imageNamed:@"apple.png"];
cell.imageView.image = cellImage;
//Set the corresponding element from our colorNames array and assign it to the textLabel property of the cell object.
cell.textLabel.text = [self.colorNames objectAtIndex: [indexPath row]];
cell.textLabel.font = [UIFont fontWithName:@"Futura-Medium" size:16.0];
cell.textLabel.textColor = [UIColor whiteColor];
//Add a subtitle
NSString *subtitle = [NSString stringWithString:@"All about the color "];
subtitle = [subtitle stringByAppendingString:cellvalue];
cell.detailTextLabel.text = subtitle;
/*Multiple sections
NSDictionary *dictionary = [dataArray objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"data"];
NSString *cellValue = [array objectAtIndex:indexPath.row];
cell.textLabel.text = cellValue;
*/
return cell;
}
//Get the selected row
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//Get the selected country
NSString *selectedCell = nil;
NSDictionary *dictionary = [dataArray objectAtIndex:indexPath.section];
NSArray *array = [dictionary objectForKey:@"data"];
selectedCell = [array objectAtIndex:indexPath.row];
NSLog(@"%@", selectedCell);
//After connecting a maintable outlet to the actual tableView in the .xib
//(Drag the outlet in the viewController and drag it to the table)
[mainTable deselectRowAtIndexPath:indexPath animated:YES];
/************************************************/
//for checkable rows
// Uncheck the previous checked row
if(self.checkedIndexPath)
{
UITableViewCell* uncheckCell = [tableView
cellForRowAtIndexPath:self.checkedIndexPath];
uncheckCell.accessoryType = UITableViewCellAccessoryNone;
}
if([self.checkedIndexPath isEqual:indexPath])
{
self.checkedIndexPath = nil;
}
else
{
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
self.checkedIndexPath = indexPath;
}
/************************************************/
}
//EDITING CELLS
// 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.
return YES;
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
//Invoke the superclass invocation of the method
[super setEditing:editing animated:animated];
//Send the same message to the tableview
[self.tableView setEditing:editing animated:YES];
//Update the enabled state of the other button in the navigation bar (a plus-sign button, for adding items)
if (editing)
{
}
else
{
}
}
//Customizing the editing style of rows. Showing delete buttons
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewCellEditingStyleDelete; //Or whatever you need
}
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[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
}
}
//MOVING ROWS
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
return YES;
}
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath {
// NSString *dyscoToMove = [dyscos objectAtIndex:sourceIndexPath.row];
// [dyscos removeObjectAtIndex:sourceIndexPath.row];
// [dyscos insertObject:stringToMove atIndex:destinationIndexPath.row];
[self.tableView reloadData];
}
- (NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath {
return proposedDestinationIndexPath;
}
@end
//Set this to the viewDidLoad - (Standard edit button in the navigation bar)
self.navigationItem.rightBarButtonItem = self.editButtonItem;
//The above button is preconfigured to send "setEditing:animated:" to the view controller when tapped.
//it toggles the button title (between Edit and Done) and the Boolean editing parameter on alternating taps
//View controller responding to setEditing:animated:
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
//Invoke the superclass invocation of the method
[super setEditing:editing animated:animated];
//Send the same message to the tableview
[tableView setEditing:editing animated:YES];
//Update the enabled state of the other button in the navigation bar (a plus-sign button, for adding items)
if (editing)
{
addButton.enabled = NO;
}
else
{
addButton.enabled = YES;
}
}
//When its table view enters editing mode, the view controller specifies a deletion control for every row except the last
//which has an insertion control.
//It does this in its implementation of the tableView:editingStyleForRowAtIndexPath: method
//Customizing the editing style of rows
- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath
{
SimpleEditableListAppDelegate *controller = (SimpleEditableListAppDelegate *)[[UIApplication sharedApplication] delegate];
if (indexPath.row == [controller countOfList]-1)
{
return UITableViewCellEditingStyleInsert;
}
else
{
return UITableViewCellEditingStyleDelete;
}
//If you don't want to have an insertion or deletion button this function can return UITableViewCellEditingStyleNone
}
//The user taps the deletion control in a row and the view controller receives a
//"tableView:commitEditingStyle:forRowAtIndexPath:" message from the table view.
//It handles this message by removing the item corresponding to the row from a model array and sending
//"deleteRowsAtIndexPaths:withRowAnimation:" to the table view.
//Updating the data-model array and deleting the row
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// If row is deleted, remove it from the list.
if (editingStyle == UITableViewCellEditingStyleDelete)
{
SimpleEditableListAppDelegate *controller = (SimpleEditableListAppDelegate *)[[UIApplication sharedApplication] delegate];
[controller removeObjectFromListAtIndex:indexPath.row];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
}
}
//Adding an Add button to the navigation bar with an action
addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addItem:)];
self.navigationItem.rightBarButtonItem = addButton;
//Responding to a tap on the Add button
//We will create a navigation controller with a single view controller whose view is put onscreen modally
//it animates upward to overlay the table view. The presentModalViewController:animated: method to do this.
- (void)addItem:sender
{
if (itemInputController == nil)
{
itemInputController = [[ItemInputController alloc] init];
}
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:itemInputController];
[[self navigationController] presentModalViewController:navigationController animated:YES];
[navigationController release];
}
//he modal, or overlay, view consists of a single custom text field.
//The user enters text for the new table-view item and then taps a Save button.
//This button sends a save: action message to its target: the view controller for the modal view.
//the view controller extracts the string value from the text field and updates the application’s data-model array with it.
- (void)save:sender
{
UITextField *textField = [(EditableTableViewTextField *)[tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]] textField];
SimpleEditableListAppDelegate *controller = (SimpleEditableListAppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *newItem = textField.text;
if (newItem != nil)
{
[controller insertObject:newItem inListAtIndex:[controller countOfList]];
}
[self dismissModalViewControllerAnimated:YES];
}
- (UITableViewCell *) getCellContentView:(NSString *)cellIdentifier {
//Adding 2 UILabels to each cell based on coordinates
//Dimensions of the cell
CGRect CellFrame = CGRectMake(0, 0, 300, 60);
//Frame for the first label
CGRect Label1Frame = CGRectMake(10, 10, 290, 25);
//Frame forthe 2d label
CGRect Label2Frame = CGRectMake(10, 33, 290, 25);
//Cell initialization
UITableViewCell *cell = [[[UITableViewCell alloc] initWithFrame:CellFrame reuseIdentifier:cellIdentifier] autorelease];
//Initialize Label with its frame coordinates
UILabel *lblTemp = [[UILabel alloc] initWithFrame:Label1Frame];
//Set a tag so we can find it later with the cellForRowAtIndexPath method
lblTemp.tag = 1;
//Add it as a subview to the cell
[cell.contentView addSubview:lblTemp];
[lblTemp release];
//Same with the 2dlabel
UILabel *lblTemp = [[UILabel alloc] initWithFrame:Label2Frame];
lblTemp.tag = 2; //tag -> 2
lblTemp.font = [UIFont boldSystemFontOfSize:12];
lblTemp.textColor = [UIColor lightGrayColor];
[cell.contentView addSubview:lblTemp];
[lblTemp release];
//We're done return the cell
return cell;
}
//Draw cells
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
cell = [self getCellContentView:CellIdentifier];
//Get our custom labels based on their tags
UILabel *lblTemp1 = (UILabel *)[cell viewWithTag:1];
UILabel *lblTemp2 = (UILabel *)[cell viewWithTag:2];
lblTemp1.text = [copyListOfItems objectAtIndex:indexPath.row];
lblTemp2.text = @"";
return cell;
}
//Set a custom height for every row
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 60; //Height=60 for every row
}
//Adding a section with animation
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationTop];
//Removing a section
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationTop];
//Generally there is also
NSMutableIndexSet *mutableIndexSet = [[NSMutableIndexSet alloc] init];
[mutableIndexSet addIndex:0];
[mutableIndexSet addIndex:2];
[mutableIndexSet addIndex:9];
//The NSIndexSet class represents an immutable collection of unique unsigned integers, known as indexes
//Create view before table
UIView *preTableView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, CGRectGetMaxX(self.tableView.bounds), 80 + kTopPadding * 2)];
//Create and add logo
UIImage *logo = [UIImage imageNamed:@"logo_home.png"];
UIImageView *imageHolder = [[UIImageView alloc] initWithFrame:CGRectMake(self.tableView.bounds.size.width / 2 - 83 / 2, kTopPadding, 83, 80)];
imageHolder.image = logo;
//Add image view to pre view
[preTableView addSubview:imageHolder];
//Add pre view to main view
self.tableView.tableHeaderView = preTableView;
//Same with
self.tableView.tableFooterView = .........
- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
return [UIView new];
}
@lamprosg
Copy link
Copy Markdown
Author

NSArray -> contents cannot be changed.

NSMutableArray -> You can add delete items with methods like -addObject: and -insertObject:atIndex:


NSMutableArray useful methods:

objectAtIndex:(NSUInteger)index: Get the value at that index.

insertObject:(id)anObject atIndex:(NSUInteger)index: Inserts object in the array’s content at the given index.

removeObjectAtIndex:(NSUInteger)index: Removes the object from the given index.

replaceObjectAtIndex:(NSUInteger)index WithObject:(id)Object: Replace object at the given index with new object.

addObject: (id)anObject: Inserts a new object at the end of the mutable array.


@lamprosg
Copy link
Copy Markdown
Author

@lamprosg
Copy link
Copy Markdown
Author

Adding views (UIView) as tableview headers and footers

self.tableView.tableHeaderView = preTableView;

self.tableView.tableFooterView = postTableView;

cell.delegate = self;

@lamprosg
Copy link
Copy Markdown
Author

[self.tableView reloadData];

//Reloads data in the tableview

@lamprosg
Copy link
Copy Markdown
Author

lamprosg commented Mar 7, 2013

Adding - Removing rows from tables
http://developer.apple.com/library/ios/#documentation/userexperience/conceptual/tableview_iphone/ManageInsertDeleteRow/ManageInsertDeleteRow.html


[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:deleteIndexPath withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];

[self.tableView beginUpdates];
[self.tableView insertRowsAtIndexPaths:insertIndexPath withRowAnimation:UITableViewRowAnimationRight];
[self.tableView endUpdates];

@lamprosg
Copy link
Copy Markdown
Author

lamprosg commented Aug 5, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment