Video Tutorial: Create a Tasks Application from the Ground Up – Part 3
In this tutorial we will be creating an application that manages tasks. The application will show you the MVC techniques for programming, how to make best use of Objective C features, as well as how to utilise storyboards to there full potential.
This is a four part tutorial, and in this part we are further implementing our AllTasks screen as well as adding the Add Task screen and fixing some bugs. Click that good old more link to watch this part, or click here to see all parts of this tutorial.
Code Listing
ICTasksBrain.m
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
// // ICTasksBrain.m // Tasks // // Created by Matthew Casey on 06/02/2012. // Copyright (c) 2012 iOSConsultancy.co.uk. All rights reserved. // #import "ICTasksBrain.h" static ICTasksBrain *mainBrainObject = nil; @interface ICTasksBrain() @property (nonatomic, strong) NSMutableArray *tasks; @property (nonatomic, strong) NSMutableArray *activity; -(void)addActivityItem:(NSString *)aItem; @end @implementation ICTasksBrain @synthesize tasks = _tasks; -(NSMutableArray *)tasks { if (!_tasks) _tasks = [[NSMutableArray alloc] init]; return _tasks; } @synthesize activity = _activity; -(NSMutableArray *)activity { if (!_activity) _activity = [[NSMutableArray alloc] init]; return _activity; } -(void)addTask:(ICTask *)aTask { [self.tasks addObject:aTask]; [self addActivityItem:[NSString stringWithFormat:@"Added Task "%@"", aTask.taskTitle]]; } -(void)completeTask:(ICTask *)aTask { [self.tasks removeObject:aTask]; [self addActivityItem:[NSString stringWithFormat:@"Completed Task "%@"", aTask.taskTitle]]; } -(void)addActivityItem:(NSString *)aItem { [self.activity insertObject:aItem atIndex:0]; } -(NSArray *)allActivity { return [self.activity copy]; } -(NSArray *)allTasksWithPriority:(ICTaskPriority)aPriority { NSPredicate *filter = [NSPredicate predicateWithFormat:@"taskPriority == %i", aPriority]; return [self.tasks filteredArrayUsingPredicate:filter]; } +(ICTasksBrain *)mainBrain { @synchronized(self) { if (!mainBrainObject) { mainBrainObject = [[ICTasksBrain alloc] init]; } } return mainBrainObject; } @end |
ICTasksTableViewController.m
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 |
// // ICTasksTableViewController.m // Tasks // // Created by Matthew Casey on 06/02/2012. // Copyright (c) 2012 iOSConsultancy.co.uk. All rights reserved. // #import "ICTasksTableViewController.h" #import "ICTasksBrain.h" @interface ICTasksTableViewController() @property (nonatomic, strong) NSArray *lowTasks; @property (nonatomic, strong) NSArray *mediumTasks; @property (nonatomic, strong) NSArray *highTasks; @end @implementation ICTasksTableViewController @synthesize lowTasks = _lowTasks; -(NSArray *)lowTasks { if (!_lowTasks) _lowTasks = [[ICTasksBrain mainBrain] allTasksWithPriority:ICTaskPriorityLow]; return _lowTasks; } @synthesize mediumTasks = _mediumTasks; -(NSArray *)mediumTasks { if (!_mediumTasks) _mediumTasks = [[ICTasksBrain mainBrain] allTasksWithPriority:ICTaskPriorityMedium]; return _mediumTasks; } @synthesize highTasks = _highTasks; -(NSArray *)highTasks { if (!_highTasks) _highTasks = [[ICTasksBrain mainBrain] allTasksWithPriority:ICTaskPriorityHigh]; return _highTasks; } - (id)initWithStyle:(UITableViewStyle)style { self = [super initWithStyle:style]; if (self) { // Custom initialization } return self; } - (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. } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; // 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; } - (void)viewWillAppear:(BOOL)animated { self.lowTasks = nil; self.mediumTasks = nil; self.highTasks = nil; [self.tableView reloadData]; [super viewWillAppear:animated]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { // Return the number of sections. return 3; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { // Return the number of rows in the section. if (section == 0) { //low priority array return self.lowTasks.count; } else if (section == 1) { //medium priority array return self.mediumTasks.count; } else if (section == 2) { //high priorirty array return self.highTasks.count; } else { return 0; //this should never happen } } -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { if (section == 0) { return @"Low Priority"; } else if (section == 1) { return @"Medium Priority"; } else if (section == 2) { return @"High Priority"; } else { return nil; //this shoudl NEVER happen } } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ICTask *ourTask = nil; UIColor *color = nil; if (indexPath.section == 0) { ourTask = [self.lowTasks objectAtIndex:indexPath.row]; color = [UIColor greenColor]; } else if (indexPath.section == 1) { ourTask = [self.mediumTasks objectAtIndex:indexPath.row]; color = [UIColor orangeColor]; } else if (indexPath.section == 2) { ourTask = [self.highTasks objectAtIndex:indexPath.row]; color = [UIColor redColor]; } UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TaskCell"]; cell.textLabel.text = ourTask.taskTitle; cell.detailTextLabel.text = ourTask.taskDescription; UIView *priorityView = [[UIView alloc] initWithFrame:CGRectMake(cell.bounds.size.width - 20, 0, 20, cell.bounds.size.height)]; priorityView.backgroundColor = color; [cell addSubview:priorityView]; 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. return YES; } */ -(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath { return @"Complete"; } // 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 ICTask *taskToComplete = nil; if (indexPath.section == 0) { taskToComplete = [self.lowTasks objectAtIndex:indexPath.row]; self.lowTasks = nil; } else if (indexPath.section == 1) { taskToComplete = [self.mediumTasks objectAtIndex:indexPath.row]; self.mediumTasks = nil; } else if (indexPath.section == 2) { taskToComplete = [self.highTasks objectAtIndex:indexPath.row]; self.highTasks = nil; } [[ICTasksBrain mainBrain] completeTask:taskToComplete]; [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject: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 { } */ /* // Override to support conditional rearranging of the table view. - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the item to be re-orderable. return YES; } */ #pragma mark - Table view delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { } @end |
ICActivityTableViewController.m
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
// // ICActivityTableViewController.m // Tasks // // Created by Matthew Casey on 06/02/2012. // Copyright (c) 2012 iOSConsultancy.co.uk. All rights reserved. // #import "ICActivityTableViewController.h" #import "ICTasksBrain.h" @interface ICActivityTableViewController() @property (nonatomic, strong) NSArray *activity; @end @implementation ICActivityTableViewController @synthesize activity = _activity; -(NSArray *)activity { if (!_activity) _activity = [[ICTasksBrain mainBrain] allActivity]; return _activity; } - (id)initWithStyle:(UITableViewStyle)style { self = [super initWithStyle:style]; if (self) { // Custom initialization } return self; } - (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. } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; // 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; } - (void)viewWillAppear:(BOOL)animated { self.activity = nil; [self.tableView reloadData]; [super viewWillAppear:animated]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } #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.activity.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ActivityCell"]; cell.textLabel.text = [self.activity objectAtIndex:indexPath.row]; 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. return YES; } */ /* // 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:[NSArray arrayWithObject: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 { } */ /* // Override to support conditional rearranging of the table view. - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { // Return NO if you do not want the item to be re-orderable. return YES; } */ #pragma mark - Table view delegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { } @end |
ICAddTaskTableViewController.h
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// // ICAddTaskTableViewController.h // Tasks // // Created by Matthew Casey on 07/02/2012. // Copyright (c) 2012 iOSConsultancy.co.uk. All rights reserved. // #import #import "ICTasksBrain.h" @interface ICAddTaskTableViewController : UITableViewController @property (nonatomic) ICTaskPriority taskPriority; @property (weak, nonatomic) IBOutlet UITextField *txtTitle; @property (weak, nonatomic) IBOutlet UITextView *txtDescription; - (IBAction)doneTapped:(id)sender; - (IBAction)cancelTapped:(id)sender; @end |
ICAddTaskTableViewController.m
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 |
// // ICAddTaskTableViewController.m // Tasks // // Created by Matthew Casey on 07/02/2012. // Copyright (c) 2012 iOSConsultancy.co.uk. All rights reserved. // #import "ICAddTaskTableViewController.h" @implementation ICAddTaskTableViewController @synthesize taskPriority = _taskPriority; @synthesize txtTitle = _txtTitle; @synthesize txtDescription = _txtDescription; - (id)initWithStyle:(UITableViewStyle)style { self = [super initWithStyle:style]; if (self) { // Custom initialization } return self; } - (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. } #pragma mark - View lifecycle - (void)viewDidLoad { [super viewDidLoad]; // 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 { [self setTxtTitle:nil]; [self setTxtDescription:nil]; [super viewDidUnload]; // Release any retained subviews of the main view. // e.g. self.myOutlet = nil; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; } - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { // Return YES for supported orientations return (interfaceOrientation == UIInterfaceOrientationPortrait); } #pragma mark - Table view delegate -(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == 0) { return nil; } else { return indexPath; } } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.taskPriority = indexPath.row; UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; cell.accessoryType = UITableViewCellAccessoryCheckmark; int i; for (i=0; i NSIndexPath *tempIP = [NSIndexPath indexPathForRow:i inSection:indexPath.section]; UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIP]; if (![tempCell isEqual:cell]) { tempCell.accessoryType = UITableViewCellAccessoryNone; } } [tableView deselectRowAtIndexPath:indexPath animated:YES]; } - (IBAction)doneTapped:(id)sender { ICTask *newTask = [[ICTask alloc] init]; newTask.taskTitle = self.txtTitle.text; newTask.taskDescription = self.txtDescription.text; newTask.taskPriority = self.taskPriority;//wher does this come from? [[ICTasksBrain mainBrain] addTask:newTask]; [self.parentViewController dismissModalViewControllerAnimated:YES]; } - (IBAction)cancelTapped:(id)sender { [self.parentViewController dismissModalViewControllerAnimated:YES]; } @end |




Recent Comments