私はiOSプログラミング(およびプログラミング全般)が初めてです。Apple が提供する Birdsighting の例 (http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/SecondiOSAppTutorial/Introduction/Introduction.html) に基づいて iPhone アプリを作成しようとしています。違いは、AddWorkout TableView Controller で Body Building のワークアウト (Birdsightings の代わりに) を作成し、ワークアウトをマスター TableView Controller に渡し、そこからワークアウトのセルを選択することで、マスターの 1 つは、そのワークアウトのイベントを筋帯ごとに表示します。次に、筋帯セルを選択し、その筋帯のワークアウトのすべての相対パラメーター (エクササイズの種類、重量、シリーズ番号など) を含む DetailView コントローラーをプッシュします。
問題は、2 番目の TableView Controller (MuscleBandViewController) で新しいレコードを渡すことができないため、detailViewController にもプッシュできないことです。なにか提案を?私は今まで 1 週間立ち往生しています (下手な英語で申し訳ありません: 私はイタリア人です)。 ここに私の DataController.h コードがあります:
#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
ここで 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
ここで私の 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
ここで私の 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
ここで私の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
ここで 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
ここで 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
ここで 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
ここで 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
最後に、私の 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