2010-05-09 5 views
0

À droite, j'essaie de faire une application qui a un calcul qui implique un chronomètre. Lorsqu'un bouton de la vue de calcul est cliqué, un chronomètre glisse à partir du bas. Tout cela fonctionne très bien, le problème que je n'arrive pas à résoudre est de savoir comment renvoyer l'heure enregistrée au contrôleur précédent pour mettre à jour un champ de texte. J'ai simplifié le code et supprimé la plupart des choses non pertinentes.Diapo de l'iPhone en passant les variables

Merci beaucoup.

CalculationViewController.h

#import <UIKit/UIKit.h> 

@interface CalculationViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> { 

IBOutlet UITextField *inputTxt; 
} 
@property (nonatomic, retain) UITextField *inputTxt; 

- (IBAction)showTimer:(id)sender; 
@end 

CalculationViewController.m

#import "CalculationViewController.h" 
#import "TimerViewController.h" 

@implementation CalculationViewController 

- (IBAction)showTimer:(id)sender { 

    TimerViewController *timerView = [[TimerViewController alloc] init]; 
    [self.navigationController presentModalViewController:timerView animated:YES]; 
} 

TimerViewController.h

#import <UIKit/UIKit.h> 

@interface TimerViewController : UIViewController { 

IBOutlet UILabel *time; 
NSTimer *myTicker; 
} 

- (IBAction)start; 
- (IBAction)stop; 
- (IBAction)reset; 
- (void)showActivity; 
@end 

TimerViewController.m

#import "TimerViewController.h" 
#import "CalculationViewController.h" 

@implementation TimerViewController 

- (IBAction)start { 
myTicker = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(showActivity) userInfo:nil repeats:YES]; 
} 

- (IBAction)stop { 
[myTicker invalidate]; 

#Update inputTxt on calculation view here 

[self dismissModalViewControllerAnimated:YES]; 
} 

- (IBAction)reset { 
time.text = @"0"; 
} 

- (void)showActivity { 
int currentTime = [time.text intValue]; 
int newTime = currentTime + 1; 

time.text = [NSString stringWithFormat:@"%d", newTime]; 
} 
@end 

Répondre

2

Un couple de façons de le faire sont:

  • utilisation NSNotificationCenter ou
  • faire CalculationViewController un délégué de TimerViewController (définir un protocole qui CalculationViewController implémente)

Dans les deux cas, la TimerViewController avertirait CalculationViewController qu'il est fait et en même temps passer les données avec lui. Donc, dans la méthode stop, il faudrait postNotificationName: object: userInfo ou appeler une méthode delegate. Ensuite, le renvoi sera effectué dans CalculationViewController à la réception de la notification.

EDIT:
Il n'y a pas nécessairement une bonne façon à chaque fois. Selon la taille et la complexité de l'application et les exigences précises de la situation, certains moyens sont meilleurs que d'autres. Le délégué de l'application est autorisé à partager des données entre les contrôleurs de vue, mais il est probablement préférable d'utiliser des notifications ou des délégués pour signaler les événements sur les contrôleurs comme vous le feriez ici.

Un protocole est une approche plus stricte et plus auto-documentée et autonome que les notifications, mais pour ce cas simple, l'un ou l'autre est bon.

Voilà comment vous pouvez la mettre en œuvre en utilisant une approche de protocole/délégué:

TimerViewController.h:

@protocol TimerViewDelegate 
-(void)timerStopped:(NSString *)timerData; 
@end 
@interface TimerViewController : UIViewController { 
    //other ivars... 
    id<TimerViewDelegate> delegate; 
} 
//other properties... 
@property (nonatomic, assign) id <TimerViewDelegate> delegate; 
//method declarations... 
@end 

TimerViewController.m:

@implementation TimerViewController 
@synthesize delegate; 
- (IBAction)stop { 
    [myTicker invalidate]; 
    NSString *timerData = @"timer data here"; 
    [self.delegate timerStopped:timerData]; 
} 
@end 

CalculationViewController.h:

#import "TimerViewController.h" 
@interface CalculationViewController : UIViewController 
    <UITableViewDelegate, UITableViewDataSource, TimerViewDelegate > { 
    ... 
} 
@end 

CalculationViewController.m:

- (IBAction)showTimer:(id)sender { 
    TimerViewController *timerView = [[TimerViewController alloc] init]; 
    timerView.delegate = self; 
    [self.navigationController presentModalViewController:timerView animated:YES]; 
    [timerView release]; 
} 

- (void)timerStopped:(NSString *)timerData 
{ 
    inputTxt.text = timerData; 
    [self dismissModalViewControllerAnimated:YES]; 
} 

Et voici la version de notification:

CalculationViewController.m:

- (IBAction)showTimer:(id)sender { 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(timerStopped:) name:@"timerStopped" object:nil]; 
    TimerViewController *timerView = [[TimerViewController alloc] init]; 
    [self.navigationController presentModalViewController:timerView animated:YES]; 
    [timerView release]; 
} 
- (void)timerStopped:(NSNotification*)notification 
{ 
    NSString *timerData = [[notification userInfo] objectForKey:@"timerData"]; 
    inputTxt.text = timerData; 
    [self dismissModalViewControllerAnimated:YES]; 
} 

TimerViewController.m:

- (IBAction)stop { 
    [myTicker invalidate]; 
    NSDictionary *dict = [NSDictionary dictionaryWithObject:@"timer data here" forKey:@"timerData"]; 
    [[NSNotificationCenter defaultCenter] postNotificationName:@"timerStopped" object:self userInfo:dict]; 
} 

Dans ce cas très simple, une apparence de notification ok pour utiliser. Dans les deux cas, aucun contrôleur ne doit connaître les détails internes les uns des autres et ne dépend pas d'un tiers comme le délégué de l'application. Ils doivent seulement se mettre d'accord sur le nom de la notification et les clés de l'utilisateur. L'approche du protocole est encore plus stricte mais auto-documentée.

+0

Quelle est la "bonne" façon de le faire? Je l'ai fait fonctionner en utilisant le délégué principal de l'application mais j'aurais préféré que le contrôleur de vue de calcul soit un délégué du contrôleur de vue du minuteur. Quel code utiliseriez-vous pour faire ceci? Merci de votre aide. – sebastyuiop

+0

Va ajouter des détails pour répondre rapidement. – DyingCactus

+0

Merci beaucoup pour ça je vais essayer le matin. – sebastyuiop

Questions connexes