2012-04-23 2 views
0

Я занимаюсь своими 4-мя диспетчерами. Первым из них является CardWalletViewController, который является табличным представлением, которое заполнено объектами карты, созданным пользователем (создание карты в порядке, поэтому я не буду публиковать код, относящийся к этому). Теперь, учитывая, что этот вид таблицы уже заполнен объектами карты, как только пользователь нажимает на ячейку, появится другой контроллер представления с именем CardDetailsViewController. Это отобразит текущие точки, которые имеет карта, а также льготы. Обратите внимание, что текущие точки отображаются через UILabel, а перки - ячейки таблицы. Значения этой ячейки таблицы (perks), статически типизируются и поступают из NSDictionary, а затем сохраняются в NSArray (для целей отображения текста ячейки). Теперь, когда я нажимаю на перк, появится PerksDetailsViewController. Это содержит UILabels, которые показывают имя перка и необходимые ему очки. Эти значения UILabels исходили от прежнего ViewController. Кроме того, PerksDetailsVC имеет кнопку с именем redeem. Нажав на нее, я перейду к другому контроллеру представления, BarCodeViewController, который позаботится о вычислении.Как решить делегат, который все еще ноль

Теперь моя забота о том, как передать выбранную карту, а также точки, соответствующие выбранному перку. Я использовал делегию для этого, но тогда кажется, что объект моей делегации не задан.

Ниже мой текущий код.

CardWalletViewController.h

#import <UIKit/UIKit.h> 
#import "Card.h" 

@class CardWalletViewController; 

@protocol CardWalletDelegate <NSObject> 

-(void)cardWalletViewController: (CardWalletViewController *)sender 
       withCurrentCard: (Card *) currentCard; 

@end 

@interface CardWalletViewController : UITableViewController 

@property (nonatomic, strong) NSMutableArray *myWallet; 

@property (nonatomic, weak) id <CardWalletDelegate> delegate; 

@end 

CardWalletViewController.m

#import "CardWalletViewController.h" 
#import "AddCardViewController.h" 
#import "Card.h" 
#import "CardDetailsViewController.h" 

@interface CardWalletViewController() 

@end 

@implementation CardWalletViewController 

@synthesize delegate = _delegate; 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 

    } 
    Card *cardDummy = [self.myWallet objectAtIndex:indexPath.row]; //myWallet is an Array where the table cell's values come from 
    cell.textLabel.text = cardDummy.name; 
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@", cardDummy.points]; 

    return cell; 
} 

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 

    //this method is responsible for showing the details of a selected card 

    CardDetailsViewController *details = [self.storyboard instantiateViewControllerWithIdentifier:@"cardDetails"]; 


    Card *selectedCard = [self.myWallet objectAtIndex:indexPath.row]; // I want this selected card to be accessible until the user clicks another card or during end of program. 

    details.myPoints = [NSString stringWithFormat:@"%@", selectedCard.points]; 

    [self.navigationController pushViewController:details animated:YES]; 


    [self.delegate cardWalletViewController:self withCurrentCard:selectedCard]; 

    //checking purposes 
    if (!self.delegate) { 
     NSLog(@"delegate is nil"); 
    } 
} 

CardDetailsViewController.m

#import "CardDetailsViewController.h" 
#import "PerksDetailsViewController.h" 
#import "Card.h" 

@interface CardDetailsViewController() 

@end 

@implementation CardDetailsViewController 

@synthesize pointsLabel = _pointsLabel; 
@synthesize myPoints = _myPoints; 

@synthesize perks = _perks; 
@synthesize datasource = _datasource; 
@synthesize datasourcePoints = _datasourcePoints; 

-(void)setupArray 
{ 
    self.perks = [[NSMutableDictionary alloc] init]; 
    [self.perks setObject:@"200" forKey:@"10% Discount"]; 
    [self.perks setObject:@"100" forKey:@"250Php Off"]; 

    self.datasource = [self.perks allKeys]; //contains perk's description 
    self.datasourcePoints = [self.perks allValues]; //contains perk's required points 
} 

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return 2; 
} 

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = (UITableViewCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

    if (!cell) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]; 
    } 

cell.textLabel.text = [self.datasource objectAtIndex:indexPath.row]; 
    cell.detailTextLabel.text = [self.datasourcePoints objectAtIndex:indexPath.row]; 

    return cell; 
} 

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    PerksDetailsViewController *perksDetails = [self.storyboard instantiateViewControllerWithIdentifier:@"detailsOfMyPerks"]; 

    [self.navigationController pushViewController:perksDetails animated:YES]; 

    perksDetails.perkDetailsLabel.text = [self.datasource objectAtIndex:indexPath.row]; 
    perksDetails.pointsLabel.text = [self.perks objectForKey:perksDetails.perkDetailsLabel.text]; 
} 

- (void)viewDidLoad 
{ 

    //show the number of points of the selected Card 
    self.pointsLabel.text = self.myPoints; 

    [self setupArray]; 

    [super viewDidLoad]; 
} 

PerksDetailsViewController.m

#import "PerksDetailsViewController.h" 
#import "Card.h" 
#import "CardWalletViewController.h" 
#import "BarcodeViewController.h" 

@interface PerksDetailsViewController() 

@end 

@implementation PerksDetailsViewController 

@synthesize pointsLabel = _pointsLabel; 
@synthesize perkDetailsLabel = _perkDetailsLabel; 
@synthesize perkDetailText = _perkDetailText; 
@synthesize pointsText = _pointsText; 
@synthesize delegate = _delegate; 
@synthesize pointsRequired = _pointsRequired; 


- (IBAction)redeemPressed:(id)sender { 
    // get required points of a perk selected 
    // cast the NSString value to an NSInteger 

    NSNumberFormatter * f = [[NSNumberFormatter alloc] init]; 
    [f setNumberStyle:NSNumberFormatterDecimalStyle]; 

    self.pointsRequired = [f numberFromString: (self.pointsLabel.text)]; 

    NSLog(@"points required by the perk %@", self.pointsRequired); 

    [self.delegate perksDetailsViewController:self didPassRequiredPoints:self.pointsRequired]; 

    if (!self.delegate){ 
     NSLog(@"delegate is nil"); 
    } 
} 

PerksDetailsViewController.h

#import <UIKit/UIKit.h> 
#import "BarcodeViewController.h" 

@class PerksDetailsViewController; 

@protocol PerksDetailsDelegate <NSObject> 

- (void)perksDetailsViewController:(PerksDetailsViewController *)sender 
      didPassRequiredPoints: (NSNumber *) requiredPoints; 

@end 

@interface PerksDetailsViewController : UIViewController 
{ 
    NSString *perkDetailText; 
    NSString *pointsText; 
    IBOutlet UILabel *perkDetailsLabel; 
    IBOutlet UILabel *pointsLabel; 
} 

@property (nonatomic, retain) IBOutlet UILabel *perkDetailsLabel, *pointsLabel; 
@property (nonatomic, retain) NSString *perkDetailText, *pointsText; 
@property (nonatomic, weak) NSNumber *pointsRequired; 

@property (nonatomic, weak) id <PerksDetailsDelegate> delegate; 

@end 

Сейчас этот ViewController является тот, который реализует эти два метода делегат

BarCodeViewController.h

#import <UIKit/UIKit.h> 

@interface BarcodeViewController : UIViewController 

@property (nonatomic, strong) NSNumber *myPoints; 

@end 

BarCodeViewController.m

#import "BarcodeViewController.h" 
    #import "CardWalletViewController.h" 
    #import "Card.h" 
    #import "PerksDetailsViewController.h" 

    @interface BarcodeViewController() <CardWalletDelegate, PerksDetailsDelegate> 

    @end 

    @implementation BarcodeViewController 

    @synthesize myPoints = _myPoints; 
    - (void)perksDetailsViewController:(PerksDetailsViewController *)sender didPassRequiredPoints:(NSNumber *)requiredPoints 
    { 
     self.myPoints = requiredPoints; 
    } 

    - (void)cardWalletViewController:(CardWalletViewController *)sender withCurrentCard:(Card *)currentCard 
    { 
     Card *myCurrentCard = currentCard; 
     [myCurrentCard.pointsToDeduct addObject:self.myPoints]; 

     NSLog(@"contents :%@", [myCurrentCard.pointsToDeduct description]); 
    } 

@end 
+1

Где код, где вы установите свойство делегата PerksDetailsViewController в? – jonkroll

+0

Скопируйте их в определенное время, следите за обновлениями. – Grauzten

ответ

4

Прежде всего, ваш объект делегат свойство декларации

@property (nonatomic, strong) id <PerksDetailsDelegate> delegate; 

должна быть изменена с strong до weak, так как ваш класс не владеет.

Во-вторых, вы никогда не устанавливаете объект-делегат для своего класса. Вот почему это nil. Я предполагаю, что BarCodeViewController (ваш класс реализации PerksDetailsDelegate) должен быть переменной экземпляра CardDetailsViewController, и вы пропустили его как делегат объекта perksDetails в didSelectRowAtIndexPath.

Редактировать.

Вы должны иметь экземпляр BarCodeViewController в CardDetailsViewController класса (названный bcvController, для примера кода ниже):

CardDetailsViewController.m

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    PerksDetailsViewController *perksDetails = [self.storyboard instantiateViewControllerWithIdentifier:@"detailsOfMyPerks"]; 
    [perksDetails setDelegate:bcvController]; // bcvController should be created before this line 
    [self.navigationController pushViewController:perksDetails animated:YES]; 

    perksDetails.perkDetailsLabel.text = [self.datasource objectAtIndex:indexPath.row]; 
    perksDetails.pointsLabel.text = [self.perks objectForKey:perksDetails.perkDetailsLabel.text]; 
} 

Edit 2

BarCodeViewController.h

#import <UIKit/UIKit.h> 
#import "CardWalletViewController.h" 
#import "Card.h" 
#import "PerksDetailsViewController.h" 

@interface BarcodeViewController : UIViewController <CardWalletDelegate, PerksDetailsDelegate> 

@property (nonatomic, strong) NSNumber *myPoints; 

@end 

BarCodeViewController.m

#import "BarcodeViewController.h" 

// @interface BarcodeViewController() 
// 
// @end 

@implementation BarcodeViewController 

@synthesize myPoints = _myPoints; 
- (void)perksDetailsViewController:(PerksDetailsViewController *)sender didPassRequiredPoints:(NSNumber *)requiredPoints 
{ 
    self.myPoints = requiredPoints; 
} 

- (void)cardWalletViewController:(CardWalletViewController *)sender withCurrentCard:(Card *)currentCard 
{ 
    Card *myCurrentCard = currentCard; 
    [myCurrentCard.pointsToDeduct addObject:self.myPoints]; 

    NSLog(@"contents :%@", [myCurrentCard.pointsToDeduct description]); 
} 

@end 

Редактировать 3

Если вы хотите отобразить BarcodeViewController, вы должны использовать bcvController этого объекта.

CardDetailsViewController.m

#import "CardDetailsViewController.h" 
#import "PerksDetailsViewController.h" 
#import "Card.h" 

@implementation CardDetailsViewController 

@synthesize pointsLabel = _pointsLabel; 
@synthesize myPoints = _myPoints; 

@synthesize perks = _perks; 
@synthesize datasource = _datasource; 
@synthesize datasourcePoints = _datasourcePoints; 
@synthesize bcvController = _bcvController; // new instance variable 

// other functions removed for clarity 

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    PerksDetailsViewController *perksDetails = [self.storyboard instantiateViewControllerWithIdentifier:@"detailsOfMyPerks"]; 
    [perksDetails setDelegate:bcvController]; 
    [self.navigationController pushViewController:perksDetails animated:YES]; 

    perksDetails.perkDetailsLabel.text = [self.datasource objectAtIndex:indexPath.row]; 
    perksDetails.pointsLabel.text = [self.perks objectForKey:perksDetails.perkDetailsLabel.text]; 
} 

- (void)viewDidLoad 
{ 

    //show the number of points of the selected Card 
    self.pointsLabel.text = self.myPoints; 

    [self setupArray]; 

    [self setBcvController:[self.storyboard instantiateViewControllerWithIdentifier:@"myBarcodeVC"]]; // use setter to retain object properly 

    [super viewDidLoad]; 
} 
+0

Спасибо! Я уже изменил его с сильного на слабое. Как мне это сделать в отношении вашего второго совета? Предоставьте мне образец в удобное для вас время. – Grauzten

+0

Я создал bcvController этим, BarcodeViewController * bcvController = [self.storyboard instantiateViewControllerWithIdentifier: @ "myBarcodeVC"]; этот хороший? – Grauzten

+0

Я просто разместил его под созданием perksDetails. Но после этого произошла ошибка: «Отправка« BarCodeViewController * _strong »в параметр несовместимого типа« id »« – Grauzten

Смежные вопросы