0

私は4つのView Controllerに関心があります。最初のものは CardWalletViewController です。これは、ユーザーが作成したカード オブジェクトによって生成されるテーブル ビューです (カードの作成は問題ないので、それに関するコードは投稿しません)。このテーブル ビューには既にカード オブジェクトが取り込まれているため、ユーザーがセルをクリックすると、CardDetailsViewController という名前の別のビュー コントローラーが表示されます。これにより、カードの現在のポイントと特典が表示されます。現在のポイントは UILabel を介して表示され、特典はテーブル ビューのセルであることに注意してください。このテーブル ビューのセル値 (特典) は静的に型指定され、NSDictionary から取得され、NSArray に格納されます (セルのテキスト表示用)。特典をクリックすると、PerksDetailsViewController が表示されます。これには、特典の名前と必要なポイントを示す UILabels が含まれています。これらの UILabels 値は、以前の ViewController からのものでした。また、PerksDetailsVC には、償還という名前のボタンがあります。それをクリックすると、計算を処理する別のビュー コントローラーである 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 は、2 つのデリゲート メソッドを実装するものです。

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
4

1 に答える 1

4

まず、デリゲート オブジェクトのプロパティ宣言

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

あなたのクラスはそれを所有していないので、からstrongに変更する必要があります。weak

次に、クラスのデリゲート オブジェクトを設定していません。それが理由ですnil。私の推測では、BarCodeViewController(PerksDetailsDelegateプロトコルを実装するクラス) は のインスタンス変数である必要があり、 のオブジェクトCardDetailsViewControllerのデリゲートとして設定するのに失敗しました。perksDetailsdidSelectRowAtIndexPath

編集。

クラスBarCodeViewController内に のインスタンスが必要です(以下のコード例では、 という名前が付けられています)。CardDetailsViewControllerbcvController

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];
}

編集 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];
}
于 2012-04-23T06:40:48.943 に答える