使用委托在视图之间传递数据

发布于 2024-11-30 22:46:18 字数 2464 浏览 1 评论 0原文

我正在构建一个实用程序应用程序,它在主视图和翻转视图之间共享数据。实际上,保存数据的并不完全是翻转视图,而是加载时作为翻转视图实例的自定义视图。我已经在之前的帖子此处解释了具体细节,但我还没有找到解决方案。我重新开发了我的代码,希望这次我能说清楚。

这里的一般概念是我在主视图中创建和存储数据,并使用 FlipViewController 中的预定义委托将其传递到翻转视图。然后在 FlipViewController 中,我将数据存储在我自己的委托中,并将其传递给实现我自己的委托方法的自定义视图。以下是代码的主要部分。

MainViewController.m(仅采用协议)

- (IBAction)showInfo:(id)sender {    

    FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideView" bundle:nil];
    controller.delegate = self;

    controller.chart = data;

    controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self presentModalViewController:controller animated:YES];

    [controller release];
}

FlipsideViewController.h

@protocol FlipsideViewControllerDelegate;
@protocol ChartDelegate;

@interface FlipsideViewController : UIViewController {
    id <FlipsideViewControllerDelegate> delegate;
    id <ChartDelegate> delegate2;
    DataModel *chart;
}

@property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
@property (nonatomic, assign) id <ChartDelegate> delegate2;
@property (nonatomic, retain) DataModel *chart;
- (IBAction)done:(id)sender;
@end


@protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
@end

@protocol ChartDelegate <NSObject>
- (void)getParams:(DataModel *)dataModel;
@end

FlipsideViewController.m

@synthesize delegate, delegate2;
@synthesize chart;

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor]; 
        if ([delegate2 respondsToSelector:@selector(getParams:)]) {
        [delegate2 getParams:chart];
    }
}

customDrawing .h

@interface customDrawing : UIView <ChartDelegate>{
    DataModel *chartData;
}
@property (nonatomic, retain) DataModel *chartData;
@end

customDrawing.m

@synthesize chartData;
-(void)getParams:(DataModel *)dataModel{
        chartData = dataModel;
}

事实证明,数据没有传递到我的自定义视图中的 ChartData 对象。帮助?

I am building a utility application which shares data between main view and flip view. Actually, it is not exactly the flip view that's holding data, it's the custom view that's an instance of the flip view when it gets loaded. I have explained the specifics in my previous thread here, but I haven't got a solution yet. And I have redeveloped my code, hopefully this time I could make myself clear.

The general concept here is I create and store data in my main view, and pass it to the flip side view using the predefined delegate in the FlipViewController. Then in the FlipViewController, I store the data in my own delegate and pass it to the custom view which implements my own delegate method. The following is the main portions of the code.

MainViewController.m (only adopts <FlipsideViewControllerDelegate> protocol)

- (IBAction)showInfo:(id)sender {    

    FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideView" bundle:nil];
    controller.delegate = self;

    controller.chart = data;

    controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self presentModalViewController:controller animated:YES];

    [controller release];
}

FlipsideViewController.h

@protocol FlipsideViewControllerDelegate;
@protocol ChartDelegate;

@interface FlipsideViewController : UIViewController {
    id <FlipsideViewControllerDelegate> delegate;
    id <ChartDelegate> delegate2;
    DataModel *chart;
}

@property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;
@property (nonatomic, assign) id <ChartDelegate> delegate2;
@property (nonatomic, retain) DataModel *chart;
- (IBAction)done:(id)sender;
@end


@protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
@end

@protocol ChartDelegate <NSObject>
- (void)getParams:(DataModel *)dataModel;
@end

FlipsideViewController.m

@synthesize delegate, delegate2;
@synthesize chart;

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor viewFlipsideBackgroundColor]; 
        if ([delegate2 respondsToSelector:@selector(getParams:)]) {
        [delegate2 getParams:chart];
    }
}

customDrawing.h

@interface customDrawing : UIView <ChartDelegate>{
    DataModel *chartData;
}
@property (nonatomic, retain) DataModel *chartData;
@end

customDrawing.m

@synthesize chartData;
-(void)getParams:(DataModel *)dataModel{
        chartData = dataModel;
}

It turns out the data didn't get passed to the chartData object in my custom view. HELP?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一袭水袖舞倾城 2024-12-07 22:46:18

你缺少基础知识。我认为您不需要代表来完成这项任务,但我们开始吧。

协议就像一份合同。在您的FlipsideViewController 类中,您定义了协议,该协议本质上表明如果您符合此协议,则必须实现此方法。

如何遵守协议?

MainViewController 中,@interface 看起来像这样

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate>

事实上,您将协议写在尖括号中意味着您承诺遵守协议,因此必须

 - (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;

MainViewController.m 中实现。

现在,当 MainNavigationController 将自身设置为委托 (controller.delegate = self;) 时,它会完成链接。这允许 FlipsideViewController 调用

[delegate flipsideViewControllerDidFinish:self];

Which 将调用 MainViewController 中定义的方法,该方法会关闭模态视图控制器。

您已经定义了第二个协议(您可以将该方法添加到第一个协议中,然后您不必采用两个协议),并且正如其他人指出的那样,您没有通过这样做来链接这些类

controller.delegate2 = self;

这不会解决您的问题。您仍然需要通过将 ChartDelegate 添加到声明中来遵守它。一旦你这样做了,你仍然无法脱离水面,因为方法不正确。

完整解决方案 - 不使用委托,因为这里并不真正需要它们

MainViewController.h

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate>

- (IBAction)showInfo:(id)sender;

@end

MainViewController.m

@implementation MainViewController

- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
    [self dismissModalViewControllerAnimated:YES];
}

- (IBAction)showInfo:(id)sender
{    
    FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideView" bundle:nil];
    controller.delegate = self;

    /*
     * The labelText property is defined in the header for FlipsideViewController
     * In this case this is the easiest way to get data from this controller to
     * the controller we are about to display
     */
    controller.labelText = @"WHAT EVER YOU WANT TO SEND"; // <---- sending data

    controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self presentModalViewController:controller animated:YES];

    [controller release];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

FlipsideViewController.h

@class FlipsideViewController;

@protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
@end

@interface FlipsideViewController : UIViewController


/*
 * These properties have been added. The label is used for displaying the text
 * and needs to be hooked up in Interface builder
 *
 * The NSString is the property that is holding the data passed from MainViewController
 */
@property (nonatomic, retain) IBOutlet UILabel *testLabel;
@property (nonatomic, copy) NSString *labelText; from MainViewControlller

@property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;

- (IBAction)done:(id)sender;

@end

FlipsideViewController.m

@implementation FlipsideViewController

@synthesize delegate = _delegate;

/*
 * We need to synthesise out properties so we get our getters and setters created
 */
@synthesize testLabel = _testLabel;
@synthesize labelText = _labelText;

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    /*
     * This is called once the view is set up and all connections have been made in 
     * interface builder. Therefore we can now set the text of our test label
     */
    self.testLabel.text = labelText;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Actions

- (IBAction)done:(id)sender
{
    [self.delegate flipsideViewControllerDidFinish:self];
}

- (void)dealloc
{
    /*
     * Memory management for the ivars we added
     */
    [_testLabel release];
    [_labelText release];
    [super dealloc];
}

@end

You are missing the fundamentals. I do not think you need delegates to achieve this task but here we go.

A protocol is like a contract. In you FlipsideViewController class you defined the protocol which essentially states if you conform to this protocol then you must implement this method.

How do you conform to a protocol?

In MainViewController the @interface will look something like this

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate>

The fact that you have the protocol written in angled brackets means that you promise to conform to the protocol and therefore have to implement

 - (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;

in your MainViewController.m.

Now when MainNavigationController set's itself as the delegate (controller.delegate = self;) it finishes the link. This allows the FlipsideViewController to call

[delegate flipsideViewControllerDidFinish:self];

Which will call the method defined in MainViewController which dismisses the modal view controller.

You have defined a second protocol (you could have added the method to the first and then you would not have to adopt two protocols) and as others have pointed out you have not linked the classes up by doing

controller.delegate2 = self;

This would not solve your problem. You would still need to conform to the ChartDelegate by adding it to the declaration. Once you have done that you will still not be out of the water because the method is not correct.

Full solution - not using delegates as they are not really required here

MainViewController.h

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate>

- (IBAction)showInfo:(id)sender;

@end

MainViewController.m

@implementation MainViewController

- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
    [self dismissModalViewControllerAnimated:YES];
}

- (IBAction)showInfo:(id)sender
{    
    FlipsideViewController *controller = [[FlipsideViewController alloc] initWithNibName:@"FlipsideView" bundle:nil];
    controller.delegate = self;

    /*
     * The labelText property is defined in the header for FlipsideViewController
     * In this case this is the easiest way to get data from this controller to
     * the controller we are about to display
     */
    controller.labelText = @"WHAT EVER YOU WANT TO SEND"; // <---- sending data

    controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self presentModalViewController:controller animated:YES];

    [controller release];
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

FlipsideViewController.h

@class FlipsideViewController;

@protocol FlipsideViewControllerDelegate
- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller;
@end

@interface FlipsideViewController : UIViewController


/*
 * These properties have been added. The label is used for displaying the text
 * and needs to be hooked up in Interface builder
 *
 * The NSString is the property that is holding the data passed from MainViewController
 */
@property (nonatomic, retain) IBOutlet UILabel *testLabel;
@property (nonatomic, copy) NSString *labelText; from MainViewControlller

@property (nonatomic, assign) id <FlipsideViewControllerDelegate> delegate;

- (IBAction)done:(id)sender;

@end

FlipsideViewController.m

@implementation FlipsideViewController

@synthesize delegate = _delegate;

/*
 * We need to synthesise out properties so we get our getters and setters created
 */
@synthesize testLabel = _testLabel;
@synthesize labelText = _labelText;

#pragma mark - View lifecycle

- (void)viewDidLoad
{
    [super viewDidLoad];

    /*
     * This is called once the view is set up and all connections have been made in 
     * interface builder. Therefore we can now set the text of our test label
     */
    self.testLabel.text = labelText;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

#pragma mark - Actions

- (IBAction)done:(id)sender
{
    [self.delegate flipsideViewControllerDidFinish:self];
}

- (void)dealloc
{
    /*
     * Memory management for the ivars we added
     */
    [_testLabel release];
    [_labelText release];
    [super dealloc];
}

@end
橪书 2024-12-07 22:46:18

您有两个属性:delegate 和 delegate2。您正在为 delegate 分配一个值,但稍后调用 delegate2 上的方法。

You have two properties: delegate and delegate2. You are assigning a value to delegate, but calling the method on delegate2 later.

So要识趣 2024-12-07 22:46:18

您需要分配 delegate2 (您的 customDrawing 类)。您仅分配委托

You need to assign the delegate2 (your customDrawing class). You are only assigning the delegate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文