I am trying to call a detail screen from a UITableView list - but the delegate is not being called in the receiving view - I'll post all the code:
list header file:
#import <UIKit/UIKit.h>
#import "tank.h"
#class iTanksV2ListViewController;
#protocol iTanksV2ListViewControllerDelegate
- (void) iTanksListViewController:(iTanksV2ListViewController *) sender choseTank:(tank *)tank;
#end
#interface iTanksV2ListViewController : UITableViewController
#property (nonatomic, strong) NSArray *tanks;
#property (weak, nonatomic) IBOutlet UITableView *tankTableView;
#property (weak, nonatomic) id <iTanksV2ListViewControllerDelegate> delegate;
#end
and the m file:
#import "iTanksV2ListViewController.h"
#import "tank.h"
#import "tankDetailViewController.h"
#interface iTanksV2ListViewController ()
#end
#implementation iTanksV2ListViewController
#synthesize tanks = _tanks;
#synthesize tankTableView = _tankTableView;
#synthesize delegate = _delegate;
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (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 setTankTableView:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return 1;//keep this section in case we do need to add sections in the future.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [self.tanks count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Tank List Table Cell";
UITableViewCell *cell = [self.tankTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero];
}
tank *thisTank = [self.tanks objectAtIndex:indexPath.row];
cell.textLabel.text = thisTank.tankNumber;
return cell;
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"Show Tank Details"])
{
}
}
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
tank *thisTank = [self.tanks objectAtIndex:indexPath.row];
[self.delegate iTanksListViewController:self choseTank:thisTank];
}
#end
and the header for the receiving file:
#import <UIKit/UIKit.h>
#import "tankGauge.h"
#import "tank.h"
#interface tankDetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *tankNumberLabel;
#property (weak, nonatomic) IBOutlet UILabel *tankProductLabel;
#property (weak, nonatomic) IBOutlet UILabel *tankAvailableProductLabel;
#property (weak, nonatomic) IBOutlet UILabel *tankMaxVolumeLabel;
#property (weak, nonatomic) IBOutlet tankGauge *tankVolumeGauge;
#property (weak, nonatomic) tank* tankToShow;
#end
...and the m file:
#import "tankDetailViewController.h"
#import "iTanksV2ListViewController.h"
#interface tankDetailViewController () <iTanksV2ListViewControllerDelegate>
#end
#implementation tankDetailViewController
#synthesize tankNumberLabel = _tankNumberLabel;
#synthesize tankProductLabel = _tankProductLabel;
#synthesize tankAvailableProductLabel = _tankAvailableProductLabel;
#synthesize tankMaxVolumeLabel = _tankMaxVolumeLabel;
#synthesize tankVolumeGauge = _tankVolumeGauge;
#synthesize tankToShow = _tankToShow;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
-(void)iTanksListViewController:(iTanksV2ListViewController *)sender choseTank:(id)tank
{
self.tankToShow = tank;
self.tankNumberLabel.text = self.tankToShow.tankNumber;
}
- (void)viewDidUnload
{
[self setTankNumberLabel:nil];
[self setTankProductLabel:nil];
[self setTankAvailableProductLabel:nil];
[self setTankMaxVolumeLabel:nil];
[self setTankVolumeGauge:nil];
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
tankTableView is an IBOutlet, so you just need to connect your tableView's delegate and data-source to your File's Owner in your xib as shown below:
Have you set that viewcontroller as the delegate for that tableview?
Related
I'm having two view controller A and B. when click button on view controllerA it will navigate to view controllerB and their is a tableview with textlabel,when i click on tableviewcell i want to navigate back into viewcontrollerA and want to pass that textlabel value back to viewcontrollerA
if you are using push seque is the worst way, reason you increase the memory in your stack trace.
you can do this in multiple ways, search once in google you get multiple answer related to this
UnWind Segue
Protocols & delegates
local database method
using Singleton class.
Using bean object method.
using Plist
finally go for NSUserDefault
I created a sample using Protocols and Delegates, as follows:
ViewController.m
#import "ViewController.h"
#import "ColorsTableViewController.h"
#interface ViewController () <ColorsDelegate>
#property (weak, nonatomic) IBOutlet UILabel *textDataLabel;
- (IBAction)goButtonTapped:(id)sender;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)sendColor:(NSString *)colorName{
self.textDataLabel.text = colorName;
}
- (IBAction)goButtonTapped:(id)sender {
ColorsTableViewController *colorsTableViewController=(ColorsTableViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"colorTableIdentifier"];
colorsTableViewController.delegate = self;
[self.navigationController pushViewController:colorsTableViewController animated:YES];
}
#end
ColorsTableViewController.h
#import <UIKit/UIKit.h>
#protocol ColorsDelegate <NSObject>
#optional
- (void)sendColor:(NSString *)colorName;
#end
#interface ColorsTableViewController : UIViewController
#property (nonatomic, assign) id<ColorsDelegate> delegate;
#end
ColorsTableViewController.m
#import "ColorsTableViewController.h"
#interface ColorsTableViewController () <UITableViewDelegate, UITableViewDataSource>
#property (weak, nonatomic) IBOutlet UITableView *colorsTableView;
#property (strong, nonatomic) NSArray *colorsArray;
#end
#implementation ColorsTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.colorsArray = #[#"Red",#"Green",#"Blue",#"Brown",#"Yellow"];
[self.colorsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:#"colorCell"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return self.colorsArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *myCell = [self.colorsTableView dequeueReusableCellWithIdentifier:#"colorCell" forIndexPath:indexPath];
UILabel *myTextLabel = [myCell.contentView viewWithTag:100];
if(!myTextLabel)
{
myTextLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 5, CGRectGetWidth(myCell.frame), CGRectGetHeight(myCell.frame))];
myTextLabel.tag = 100;
}
myTextLabel.text = self.colorsArray[indexPath.row];
[myCell.contentView addSubview:myTextLabel];
return myCell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *myCell = (UITableViewCell *)[self.colorsTableView cellForRowAtIndexPath:indexPath];
UILabel *myTextLabel = [myCell.contentView viewWithTag:100];
if(myTextLabel)
{
[_delegate sendColor:myTextLabel.text];
}
}
Screenshot:
Here is my GitHub Link, please download and check:
https://github.com/k-sathireddy/sendDataBack
What I'm trying to do is have a list of counties in a table view. When you click a county, another table view will show a list of resources you can select. I am using storyboards and Objective-C.
Here is my storyboard.
I don't want to nest the options into one table view because I think there are too many choices to be efficiently nested.
Here is my .h file for the county list table view:
// SecondViewController.h
#import <UIKit/UIKit.h>
#interface SecondViewController : UIViewController <UITableViewDelegate,
UITableViewDataSource>
#end
My .m file for the county list table view:
// SecondViewController.m
#import "SecondViewController.h"
#import "DetailViewController.h"
#interface SecondViewController ()
#property (nonatomic, strong) NSArray *tableData;
#property (nonatomic, strong) IBOutlet UITableView *tableView;
#end
#implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.tableData = #[#"Carter", #"Greene", #"Hancock", #"Hawkins", #"Johnson", #"Sullivan", #"Unicoi", #"Washington"];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.destinationViewController isKindOfClass:[DetailViewController class]])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *name = self.tableData[indexPath.row];
[(CountyViewController *)segue.destinationViewController setName:name];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.tableData.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = self.tableData[indexPath.row];
return cell;
}
#end
The County Resources .h file I want to display in table view format:
// CountyViewController.h
#import <UIKit/UIKit.h>
#interface CountyViewController : UIViewController <UITableViewDelegate,
UITableViewDataSource>
#property (nonatomic, strong) IBOutlet UITableView *tableView;
#end
The .m file:
// CountyViewController.m
#import "CountyViewController.h"
#import "CountyDetail.h"
#interface CountyViewController ()
#end
#implementation CountyViewController {
NSArray *counties;
}
#synthesize tableView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize table data
counties = [NSArray arrayWithObjects:#"Resource1", #"Resource2", #"Resource3", #"Resource4", #"Resource5", #"Resource6", #"Resource7", #"Resource8", #"Resource9", nil];
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [counties count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text = [counties objectAtIndex:indexPath.row];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showCountyInfo"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
CountyDetail *destViewController = segue.destinationViewController;
destViewController.countyName = [counties objectAtIndex:indexPath.row];
}
}
#end
Lastly, the detail of the resource clicked:
// CountyDetail.h
#import <UIKit/UIKit.h>
#interface CountyDetail : UIViewController
#property (nonatomic, strong) IBOutlet UILabel *countyLabel;
#property (nonatomic, strong) NSString *countyName;
#end
And the .m file:
// CountyDetail.m
#import "CountyDetail.h"
#interface CountyDetail ()
#end
#implementation CountyDetail
#synthesize countyLabel;
#synthesize countyName;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Set the Label text with the selected county
countyLabel.text = countyName;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
So my goal is to have the county selection go to another array of resources in another table view. I'm guessing I'm going to need a lot more arrays, but I just don't know the format or structure. I hope this is enough information, and if anyone can explain their answer, that would be extremely helpful. Thanks!
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
You can follow this delegate send the message to another tableView or others.
I have loaded a table view with NSArray data. Now, I want to play a video in a detail view. The video played depends on what cell the user clicks.
How do I test the cell clicked and load a video from the array based on that?
I am using Xcode 5 for iOS 7.
Here is my ViewController.m
#import "ViewController.h"
#import "VideoDetailViewController.h"
#interface ViewController ()
{
NSMutableArray * titlearray;
NSMutableArray * arrayVidSrc;
}
#end
#implementation ViewController
#synthesize mytableview;
- (void)viewDidLoad
{
[super viewDidLoad];
//sets delegate methods of table view
self.mytableview.delegate=self;
self.mytableview.dataSource=self;
//assigns values to objects in array's
titlearray = [[NSMutableArray alloc]initWithObjects:#"intro", #"skating",nil];
arrayVidSrc = [[NSMutableArray alloc]initWithObjects:#"Step1-Intro.mp4", #"Step2-Skating.mp4", nil];
}
// returns one section in the table
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
//counts the items in the title array
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [titlearray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier =#"vidCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath: indexPath];
cell.textLabel.text = [titlearray objectAtIndex:indexPath.row];
return cell;
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showDetailsSeg"]) {
NSIndexPath *indexpath =nil;
NSString *titlestring =nil;
indexpath = [mytableview indexPathForSelectedRow];
titlestring = [titlearray objectAtIndex:indexpath.row];
NSURL * movieURL = [arrayVidSrc objectAtIndex:indexpath.row];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL: movieURL];
[[player view] setFrame: [self.view bounds]];
[self.view addSubview: [player view]];
[player play];
[[segue destinationViewController] setTitlecontents:titlestring];
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
And here is my ViewController.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
//allows us to use the delegate methods of table view
#interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (weak, nonatomic) IBOutlet UITableView *mytableview;
#end
I have a custom view controller class VideoDetailViewController.m:
#import "VideoDetailViewController.h"
#interface VideoDetailViewController ()
#end
#implementation VideoDetailViewController
#synthesize arrayVidSrc = _arrayVidSrc;
#synthesize titlelabel;
#synthesize navBar;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.titlelabel.text = self.titlecontents;
self.navBar.title = self.titlecontents;
//video load from array
// NSURL * movieURL = [_arrayVidSrc objectAtIndex:NSIndexPath.row];
//Play the movie now
/*MPMoviePlayerViewController *playercontroller = [[MPMoviePlayerViewController alloc] initWithContentURL:movieURL];
[self presentMoviePlayerViewControllerAnimated:playercontroller];
playercontroller.moviePlayer.movieSourceType = MPMovieSourceTypeFile;
[playercontroller.moviePlayer play];
playercontroller = nil;*/
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
and the .h file that goes with it:
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface VideoDetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UINavigationItem *navBar;
#property (weak, nonatomic) IBOutlet UILabel *selectedRow;
#property (strong, nonatomic) NSString * titlecontents;
#property (weak, nonatomic) IBOutlet UILabel * titlelabel;
#property (strong, nonatomic) NSArray *arrayVidSrc;
#end
Implement the method - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender. The sender is the cell that was clicked. You can then call something like [self.tableView indexPathForCell:sender] to get the cell address and use the row of the returned index path to pick the video out of your array.
The new view controller that will be shown when the segue finishes is available within the prepareForSegue:: method as [segue destinationViewController] and you can pass it whatever it will need.
it's now a couple of days I've been struggling with UISplitViewControllers, here's my problem: I have a master view which is declared as follows
#import <UIKit/UIKit.h>
#import "DetailViewController.h"
#class DetailViewController;
#interface MasterViewController : UITableViewController {
NSMutableArray *title, *subTitle;
unsigned int quantity;
}
#property (strong, nonatomic) DetailViewController *detailViewController;
#end
In the master's .m file everything works correctly (I'm able to populate the table from a sqlite db and show the contents in rows). When it comes to select one row and populate the detailed view on the right side nothing happens. Here is the row selection:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
MyObject itemFromDB;
/*
... DB stuff here ...
*/
self.detailViewController.detailItem = itemFromDB;
}
Here's now the DetailViewController implementation:
#interface DetailViewController : UIViewController <UISplitViewControllerDelegate>
#property (strong, nonatomic) MyObject *detailItem;
#property (weak, nonatomic) IBOutlet UILabel *name, *phone;
#end
And the detail's .m:
#import "DetailViewController.h"
#interface DetailViewController ()
- (void)configureView;
#end
#implementation DetailViewController
- (void)setDetailItem:(MyObject *)newItem
{
if (_detailItem != newItem) {
_detailItem = newItem;
[self configureView];
}
}
- (void)configureView
{
if (self.detailItem) {
self.name.text = [self.detailItem name];
self.phone.text = [self.detailItem phone];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self configureView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
In simple words: the detail isn't noticing any changes after the selection of a row. Any help?
You never defined self.detailViewController. You should do this:
self.detailViewController = self.splitViewController.viewControllers[1];
I'm new to iOS programing (and programming in general). I'm trying to do an iPhone App based on the Birdsighting example provided by Apple (http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/SecondiOSAppTutorial/Introduction/Introduction.html). The difference is that I will create Body Building's workouts (instead of Birdsightings) in an AddWorkout TableView Controller, pass the workout to the Master TableView Controller and from there being able, by selecting a workout's cell, to display a second TableView Controller similar to the Master's one, that shows events of that workout sorted by muscle bands; then, selecting a muscle band cell, pushing a DetailView Controller with all relative parameters of that muscle band's workout (exercise type, weight, series number....). All this is embedded in a navigation controller.
The problem is that I can't pass a new record on the second TableView Controller (MuscleBandViewController) and therefore I can't neither push it to the detailViewController. Any suggestion? I'm stuck for a week 'til now (sorry for my bad English: I'm Italian).
Here is my DataController.h code:
#import <Foundation/Foundation.h>
#class Workouts;
#interface IFitDataController : NSObject
#property (nonatomic, copy)NSMutableArray *masterWorkoutsList;
#property (nonatomic, copy)NSMutableArray *masterMuscleBandList;
- (NSUInteger)countOfList;
- (NSUInteger)countOfMuscleBandList;
- (Workouts *)objectInListAtIndex:(NSUInteger)theIndex;
- (Workouts *)objectInMasterMuscleBandListAtIndex:(NSUInteger)index;
- (void)addWorkoutsWithWorkouts:(Workouts *)thisWorkout;
#end
Here DataController.m:
#import "IFitDataController.h"
#import "Workouts.h"
#interface IFitDataController ()
- (void)initializeDefaultDataList;
#end
#interface IFitDataController ()
- (void)initializeMuscleBandDataList;
#end
#implementation IFitDataController
- (void)initializeDefaultDataList {
NSMutableArray *workoutsList = [[NSMutableArray alloc] init];
self.masterWorkoutsList = workoutsList;
Workouts *thisWorkout;
NSDate *today = [NSDate date];
thisWorkout = [[Workouts alloc] initWithName:#"Pectorals" exercise:#"Pectoral Machine" series:#"3" nActionsInSerie:#"10" measure:#"Kg" weight:#"25" date:today comment:#"Add your comment"];
[self addWorkoutsWithWorkouts:thisWorkout];
}
- (void)setMasterWorkoutsList:(NSMutableArray *)newList {
if (_masterWorkoutsList != newList) {
_masterWorkoutsList = [newList mutableCopy];
}
}
- (void)initializeMuscleBandDataList {
NSMutableArray *muscleBandList = [[NSMutableArray alloc]init];
self.masterMuscleBandList = muscleBandList;
Workouts *thisWorkout;
NSDate *today = [NSDate date];
thisWorkout = [[Workouts alloc] initWithName:#"Pectorals" exercise:#"Pectoral Machine" series:#"3" nActionsInSerie:#"10" measure:#"Kg" weight:#"25" date:today comment:#"Add your comment"];
[self addWorkoutsWithWorkouts:thisWorkout];
}
- (void)setMasterMuscleBandList:(NSMutableArray *)newMuscleBandList {
if ((_masterMuscleBandList != newMuscleBandList)) {
_masterMuscleBandList = [newMuscleBandList mutableCopy];
}
}
- (id)init {
if (self = [super init]) {
[self initializeDefaultDataList];
[self initializeMuscleBandDataList];
return self;
}
return nil;
}
- (NSUInteger)countOfList {
return [self.masterWorkoutsList count];
}
- (NSUInteger)countOfMuscleBandList {
return [self.masterMuscleBandList count];
}
- (Workouts *)objectInListAtIndex:(NSUInteger)theIndex {
return [self.masterWorkoutsList objectAtIndex:theIndex];
}
- (Workouts *)objectInMasterMuscleBandListAtIndex:(NSUInteger)index {
return [self.masterMuscleBandList objectAtIndex:index];
}
- (void)addWorkoutsWithWorkouts:(Workouts *)thisWorkout {
[self.masterWorkoutsList addObject:thisWorkout];
[self.masterMuscleBandList addObject:thisWorkout];
}
#end
Here my AddWorkoutViewController.h:
#import <UIKit/UIKit.h>
#define muscleBandComponent 0
#define exercisesComponent 1
#class Workouts;
#interface AddWorkoutViewController : UITableViewController <UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource> {
IBOutlet UIPickerView *exercisePicker;
IBOutlet UITextView *commentInserted;
NSArray *_exercisesForPicker;
NSArray *_muscleBandForPicker;
NSDictionary *totalExercises;
}
#property (weak, nonatomic) IBOutlet UITextField *muscleBandName;
#property (weak, nonatomic) IBOutlet UITextField *exerciseName;
#property (weak, nonatomic) IBOutlet UILabel *nSeries;
#property (weak, nonatomic) IBOutlet UILabel *measureType;
#property (weak, nonatomic) IBOutlet UILabel *nActionsInSerie;
#property (weak, nonatomic) IBOutlet UILabel *weightPerformed;
#property (strong, nonatomic) IBOutlet UITextView *commentInserted;
#property (retain, nonatomic) IBOutlet UIPickerView *exercisePicker;
#property (retain, nonatomic) NSArray *muscleBandForPicker;
#property (retain, nonatomic) NSDictionary *totalExercises;
#property (retain, nonatomic) NSArray *exercisesForPicker;
- (IBAction)nSeriesStepper:(id)sender;
- (IBAction)nActionsSerieStepper:(id)sender;
- (IBAction)weightStepper:(id)sender;
- (void) closeKeyboard;
#property (strong, nonatomic) Workouts *workout;
#end
Here my AddWorkoutViewController.m:
#import "AddWorkoutViewController.h"
#import "Workouts.h"
#import "IFitDataController.h"
#interface AddWorkoutViewController ()
#end
#implementation AddWorkoutViewController
#synthesize exercisePicker;
#synthesize totalExercises;
#synthesize exercisesForPicker;
#synthesize muscleBandForPicker;
#synthesize nSeries;
#synthesize nActionsInSerie;
#synthesize weightPerformed;
#synthesize commentInserted;
- (IBAction)nSeriesStepper:(id)sender {
self.nSeries.text = [NSString stringWithFormat:#"%d", [[NSNumber numberWithDouble:[(UIStepper *)sender value]] intValue]];
}
- (IBAction)nActionsSerieStepper:(id)sender {
self.nActionsInSerie.text = [NSString stringWithFormat:#"%d", [[NSNumber numberWithDouble:[(UIStepper *)sender value]] intValue]];
}
- (IBAction)weightStepper:(id)sender {
self.weightPerformed.text = [NSString stringWithFormat:#"%d", [[NSNumber numberWithDouble:[(UIStepper *)sender value]] intValue]];
}
- (IBAction) go:(id)sender
{
[self closeKeyboard];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ReturnInput"]) {
if ([self.exerciseName.text length] || [self.muscleBandName.text length]) {
Workouts *thisWorkout;
NSDate *today = [NSDate date];
thisWorkout = [[Workouts alloc] initWithName:self.muscleBandName.text exercise:self.exerciseName.text series:self.nSeries.text nActionsInSerie:self.nActionsInSerie.text measure:self.measureType.text weight:self.weightPerformed.text date:today comment:self.commentInserted.text];
self.workout = thisWorkout;
}
}
}
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField {
if ((textField == self.exerciseName) || (textField == self.muscleBandName)) {
[textField resignFirstResponder];
}
return YES;
}
- (void) closeKeyboard
{
if([commentInserted isFirstResponder])
{
[commentInserted resignFirstResponder];
}
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
// Initialization code
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSBundle *bundle = [NSBundle mainBundle];
NSString *plistPath = [bundle pathForResource:#"muscleBands" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
self.totalExercises = dictionary;
NSArray *components = [self.totalExercises allKeys];
NSArray *sorted = [components sortedArrayUsingSelector:#selector(compare:)];
self.muscleBandForPicker = sorted;
NSString *selectedMuscleBand = [self.muscleBandForPicker objectAtIndex:0];
NSArray *array = [totalExercises objectForKey:selectedMuscleBand];
self.exercisesForPicker = array;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table view data source
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 2;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
if (component == muscleBandComponent)
return [self.muscleBandForPicker count];
return [self.exercisesForPicker count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (component == muscleBandComponent)
return [self.muscleBandForPicker objectAtIndex:row];
return [self.exercisesForPicker objectAtIndex:row];
}
-(void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (component == muscleBandComponent) {
NSString *selectedMuscleBand = [self.muscleBandForPicker objectAtIndex:row];
NSArray *array = [totalExercises objectForKey:selectedMuscleBand];
self.exercisesForPicker = array;
[exercisePicker selectRow:0 inComponent:exercisesComponent animated:YES];
[exercisePicker reloadComponent:exercisesComponent];
self.muscleBandName.text = [muscleBandForPicker objectAtIndex:row];
return;
}
self.exerciseName.text = [exercisesForPicker objectAtIndex:row];
}
#end
Here my MasterViewController.h:
#import <UIKit/UIKit.h>
#class IFitDataController;
#class Workouts;
#interface IFitMasterViewController : UITableViewController
#property (strong, nonatomic) IFitDataController *dataController;
#property (strong, nonatomic) IFitDataController *muscleBandDataController;
#property (strong, nonatomic) Workouts *thisWorkout;
- (IBAction)done:(UIStoryboardSegue *)segue;
- (IBAction)cancel:(UIStoryboardSegue *)segue;
#end
Here MasterViewController.m::
#import "IFitMasterViewController.h"
#import "IFitDetailViewController.h"
#import "IFitDataController.h"
#import "Workouts.h"
#import "AddWorkoutViewController.h"
#import "IFitMuscleBandViewController.h"
#implementation IFitMasterViewController
- (IBAction)done:(UIStoryboardSegue *)segue {
if ([[segue identifier] isEqualToString:#"ReturnInput"]) {
AddWorkoutViewController *addController = [segue sourceViewController];
if (addController.workout) {
[self.dataController addWorkoutsWithWorkouts:addController.workout];
[[self tableView] reloadData];
}
[self dismissViewControllerAnimated:YES completion:NULL];
}
}
- (IBAction)cancel:(UIStoryboardSegue *)segue
{
if ([[segue identifier] isEqualToString:#"CancelInput"]) {
[self dismissViewControllerAnimated:YES completion:NULL];
}
}
- (void)awakeFromNib
{
[super awakeFromNib];
self.dataController = [[IFitDataController alloc]init];
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.dataController countOfList];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"WorkoutCell";
static NSDateFormatter *formatter = nil;
if (formatter == nil) {
formatter = [[NSDateFormatter alloc]init];
[formatter setDateStyle:NSDateFormatterFullStyle];
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Workouts *workoutAtIndex = [self.dataController objectInListAtIndex:indexPath.row];
[[cell textLabel]setText:[formatter stringFromDate:(NSDate *)workoutAtIndex.date]];
[[cell detailTextLabel]setText:workoutAtIndex.comment];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return NO;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowMuscleBandList"]) {
IFitMasterViewController *muscleBandViewController = [segue destinationViewController];
muscleBandViewController.thisWorkout = [self.muscleBandDataController objectInListAtIndex:[self.tableView indexPathForSelectedRow].row];
}
}
#end
Here MuscleBandViewController.h:
#import <UIKit/UIKit.h>
#class IFitDataController;
#interface IFitMuscleBandViewController : UITableViewController
#property (strong, nonatomic) Workouts *thisWorkout;
#property (strong, nonatomic) IFitDataController *dataController;
#property (strong, nonatomic) IFitDataController *muscleBandDataController;
#end
Here MuscleBandViewController.m:
#import "IFitMasterViewController.h"
#import "IFitDetailViewController.h"
#import "IFitDataController.h"
#import "Workouts.h"
#import "AddWorkoutViewController.h"
#import "IFitMuscleBandViewController.h"
#class IFitDataController;
#implementation IFitMuscleBandViewController
- (void)awakeFromNib
{
[super awakeFromNib];
self.muscleBandDataController = [[IFitDataController alloc]init];
}
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.muscleBandDataController countOfMuscleBandList];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"MuscleBandCell";
static NSDateFormatter *formatter = nil;
if (formatter == nil) {
formatter = [[NSDateFormatter alloc]init];
[formatter setDateStyle:NSDateFormatterFullStyle];
}
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Workouts *workoutAtIndex = [self.muscleBandDataController objectInMasterMuscleBandListAtIndex:indexPath.row];
[[cell textLabel]setText:workoutAtIndex.muscleBand];
[[cell detailTextLabel]setText:workoutAtIndex.comment];
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowWorkoutDetails"]) {
IFitDetailViewController *detailViewController = [segue destinationViewController];
detailViewController.thisWorkout = [self.muscleBandDataController objectInMasterMuscleBandListAtIndex:[self.tableView indexPathForSelectedRow].row];
}
}
#end
Here DetailViewController.h:
#import <UIKit/UIKit.h>
#class Workouts;
#interface IFitDetailViewController : UITableViewController
#property (strong, nonatomic) Workouts *thisWorkout;
#property (weak, nonatomic) IBOutlet UILabel *muscleBandLabel;
#property (weak, nonatomic) IBOutlet UILabel *exerciseLabel;
#property (weak, nonatomic) IBOutlet UILabel *seriesLabel;
#property (weak, nonatomic) IBOutlet UILabel *nActionsInSerieLabel;
#property (weak, nonatomic) IBOutlet UILabel *measureLabel;
#property (weak, nonatomic) IBOutlet UILabel *weightLabel;
#property (weak, nonatomic) IBOutlet UILabel *dateLabel;
#property (weak, nonatomic) IBOutlet UILabel *commentLabel;
#end
and finally my DetailViewController.m:
#import "IFitDetailViewController.h"
#import "Workouts.h"
#interface IFitDetailViewController ()
- (void)configureView;
#end
#implementation IFitDetailViewController
#pragma mark - Managing the detail item
- (void)setWorkout:(Workouts *)newWorkout
{
if (_thisWorkout != newWorkout) {
_thisWorkout = newWorkout;
// Update the view.
[self configureView];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
Workouts *theWorkout = self.thisWorkout;
static NSDateFormatter *formatter = nil;
if (formatter == nil) {
formatter = [[NSDateFormatter alloc]init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
}
if (theWorkout) {
self.muscleBandLabel.text = theWorkout.muscleBand;
self.exerciseLabel.text = theWorkout.exercise;
self.seriesLabel.text = theWorkout.series;
self.nActionsInSerieLabel.text = theWorkout.nActionsInSerie;
self.measureLabel.text = theWorkout.measure;
self.weightLabel.text = theWorkout.weight;
self.title = [formatter stringFromDate:(NSDate *)theWorkout.date];
self.commentLabel.text = theWorkout.comment;
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self configureView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end