gpt4 book ai didi

objective-c - 如何解决仍然为零的委托(delegate)

转载 作者:行者123 更新时间:2023-11-28 19:19:14 25 4
gpt4 key购买 nike

我担心我的 4 个 View Controller 。第一个是 CardWalletViewController,它是一个 TableView ,由用户创建的卡片对象填充(卡片创建没问题,所以我不会发布相关代码)。现在,假设这个 TableView 已经填充了卡片对象,一旦用户点击一个单元格,另一个名为 CardDetailsViewController 的 View Controller 就会出现。这将显示卡的当前点数以及津贴。请注意,当前点数是通过 UILabel 显示的,额外的是表格 View 的单元格。此 TableView 的单元格值(特权)是静态类型的,来自 NSDictionary,然后存储在 NSArray 中(用于单元格的文本显示目的)。现在,当我点击一个 perk 时,PerksDetailsViewController 就会出现。这包含 UILabels,它显示 perk 的名称和它需要的点数。这些 UILabels 值来自以前的 ViewController。此外,PerksDetailsVC 有一个名为 redeem 的按钮。单击它后,我将转到另一个 View Controller BarCodeViewController,它负责计算。

现在我关心的是如何传递选定的卡片,以及与选定的额外津贴相对应的点数。我已经使用委托(delegate)来执行此操作,但似乎未设置我的委托(delegate)对象。

下面是我当前的代码。

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 是实现这两个委托(delegate)方法的那个

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

最佳答案

首先,你的委托(delegate)对象属性声明

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

应该从 strong 更改为 weak,因为您的类不拥有它。

其次,您永远不会为您的类设置委托(delegate)对象。这就是为什么它是 nil 的原因。我的猜测是 BarCodeViewController(您的 PerksDetailsDelegate 协议(protocol)实现类)应该是 CardDetailsViewController 的实例变量,而您错过了将其设置为委托(delegate)didSelectRowAtIndexPath 中的 perksDetails 对象。

编辑。

您应该在 CardDetailsViewController 类中有一个 BarCodeViewController 的实例(命名为 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];
}

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

关于objective-c - 如何解决仍然为零的委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10275562/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com