使用AppDelegate来回传递数据 [英] Passing data back and forth using AppDelegate

查看:82
本文介绍了使用AppDelegate来回传递数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我将构建一个应用程序来学习Objective-C的基础知识.如果有任何不清楚的地方,请告诉我,我将编辑我的问题.

To start I am building an app to learn the basics of Objective-C. If there is anything unclear please let me know and I will edit my question.

该应用应该具有下一个功能. 执行该应用程序时,打开相机预览.顶部有一个前往TemplateController的按钮,用户可以在其中选择要从UICollectionView中选择的框架数组.用户选择模板并返回到摄像机预览".用户拍照,并且带有选定帧的图片显示在PreviewController中.如果用户不喜欢该框架,并希望将其切换为另一框架. PreviewController顶部有一个按钮,可转到TemplateController,选择框架,然后使用新框架再次返回到PreviewController.

The app is supposed to have the next functionality. Open the camera preview when the app is executed. On the top there is a button to go to a TemplateController where the user can select an array of frames to select from a UICollectionView. User selects the Template and returns to the Camera Preview. User takes a picture and the picture with the frame selected is shown in the PreviewController. If the user doesn't like the frame and wants to switch it for another one. PreviewController has button on top to go to the TemplateController, select the frame and go back again to the PreviewController with the new frame.

我不想每次都为框架创建对象.我希望AppDelegate持有该对象.要让它保持说下去的效果?(对不起,英语不是我的母语).

I do not want to create an object for the frame everytime. I want the AppDelegate to hold that object. To keep it alive per say?(sorry, English is not my mother tongue).

我当时想使用NSUserDefaults,但我真的想使用AppDelegate来做.因此,目前还不能使用NSUserDefaults.

I was thinking to use NSUserDefaults BUT I really want to do it using the AppDelegate. So at this point NSUserDefaults is not an option.

现在,我正在使用带有导航控制器的情节提要.屏幕截图在这里可用 现在,当我从TemplateController传递到PreviewController时,我的代码如下:

Now, I am using storyboards with a navigation controller. A screenshot is available here Right now when I pass from the TemplateController to my PreviewController my code looks like this:

从MainController或PreviewController到达TemplateController

Reaching TemplateController from MainController or PreviewController

- (IBAction)showFrameSelector:(id)sender 
{
    UIStoryboard *storyboard;
    storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil];
    TemplateController *templateController = [storyboard instantiateViewControllerWithIdentifier:@"TemplateController"];
    templateController.frameDelegate = self;
    [self presentViewController:templateController animated:YES completion:nil];
}

将数据从TemplateController传递到其控制器的命运(MainController或PreviewController)

Passing the data from TemplateController to its controller's destiny (Either MainController or PreviewController)

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    _selectedLabelStr = [self.frameImages[indexPath.section] objectAtIndex:indexPath.row];
    [self.collectionView deselectItemAtIndexPath:indexPath animated:NO];

    [self dismissViewControllerAnimated:YES completion:^{
    if ([self.frameDelegate respondsToSelector:@selector(templateControllerLoadFrame:)]) 
    {
            [self.frameDelegate performSelector:@selector(templateControllerLoadFrame:) withObject:self];
    }
    }];
}

这会将选定的帧加载到PreviewController

This loads the selected frame in PreviewController

- (void)templateControllerLoadFrame:(TemplateController *)sender
{
    UIImage *tmp = [UIImage imageNamed:sender.selectedLabelStr];
    _frameImageView.image = tmp;      
}

我的问题是,我不清楚我必须对AppDelegate进行哪些更改(目前尚未更改).什么是实现这一目标的最佳方法? 主要问题是在拍摄静止图像之前选择了Tamplate.如果我在拍照后选择了相框,则会显示出来.

My problem is, I don't have very clear what changes I have to do on the AppDelegate(it is untouched right now). What would be the best approach to accomplish this? Main issue is when Tamplate is chosen before taking the still image. If I select the frame after taking the picture then it displays.

推荐答案

我不确定我是否理解您的问题.将对象填充到应用程序委托解决方案中可能不是最好的方法.实际上,我相信您应该查看Apple在视图控制器之间进行通信所使用的委托模式.请注意,您似乎已经在执行委托模式的一半.例如,您将PreviewController设置为TemplateController的frameDelegate.

I am not certain that I understand your question. Stuffing an object into the app delegate solution may not be the best way forward. In fact I believe you ought to look at the delegation pattern that is used by Apple to communicate between view controllers. Please note that you appear to be doing half of the delegate pattern already. For example you make your PreviewController a frameDelegate of the TemplateController.

因此,我想您将具有以下类似内容,可将信息从TemplateController传输回PreviewController.请注意,我包括了为segue做准备,因为这是将数据对象向前推送的常见模式(如果您将segue从PreviewController连接到TemplateController并在您的操作方法中调用performSegueWithIdentifier:@"SegueTitle",则将被调用) .使用"templateControllerDidFinish"委托方法是一种常用模式,用于在关闭信息时将信息从TemplateController推回.

So I would think you'd have something like the following to transfer information from TemplateController back to the PreviewController. Note that I've included prepare for segue as that is a common pattern to push a data object forward (it will be called if you connect a segue from the PreviewController to the TemplateController and in your action method call performSegueWithIdentifier:@"SegueTitle"). Use of the "templateControllerDidFinish" delegation method is a common pattern used to push information back from TemplateController when it closes.

TemplateController.h

@class TemplateController;
@protocol TemplateControllerDelegate <NSObject>
-(void) templateControllerDidFinish :(TemplateController*)controller;
@end

@interface TemplateController : UIViewController 
@property (nonatomic, weak) id <TemplateControllerDelegate>delegate;
...
@end

TemplateController.m
 //! The internals for this method can also be called from wherever in your code you need to dismiss the TemplateController by copying the internal 
-(IBAction)doneButtonAction:(id)sender
{

    __weak TemplateController*weakSelf = self;
    [self dismissViewControllerAnimated:YES completion:^{
        [self.delegate templateControllerDidFinish:weakSelf];
    }];
}

PreviewController.h

#import "TemplateController.h"

@interface PreviewController<TemplateControllerDelegate>
...
@end

PreviewController.m

@implementation
...
-(void) templateControllerDidFinish :(TemplateController*)controller
{
    self.dataProperty = controller.someImportantData;
    ...
}

...

-(void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
    if ( [[segue identifier]isEqualToString:@""] ) 
    {
         TemplateController *tc = [segue destinationViewController];
         tc.delegate = self;
         tc.data = [someDataObjectFromPreviewController];
    }
}

要解决此问题,请执行以下操作:

To fix this situation a bit more:

  1. 将一个序列从PreviewController添加到TemplateController (按住Ctrl键将其从预览"视图控制器拖动到模板控制器" 在文档大纲模式下)
  2. 在身份检查器中命名segue标识符
  3. 从以下位置更改显示视图控制器的代码:

  1. Add a segue from the PreviewController to the TemplateController (Ctrl-drag from Preview view controller to the Template Controller in the document outline mode)
  2. Name the segue identifier in the identity inspector
  3. Change your code that presents the view controller from:

  • (IBAction)showFrameSelector:(id)发送者 { UIStoryboard *故事板; storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone"捆绑包:无]; TemplateController * templateController = [storyboard InstantiateViewControllerWithIdentifier:@"TemplateController"]; templateController.frameDelegate =自我; [自身presentViewController:templateController动画:是完成:无]; }
  • (IBAction)showFrameSelector:(id)sender { UIStoryboard *storyboard; storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPhone" bundle:nil]; TemplateController *templateController = [storyboard instantiateViewControllerWithIdentifier:@"TemplateController"]; templateController.frameDelegate = self; [self presentViewController:templateController animated:YES completion:nil]; }

- (IBAction)showFrameSelector:(id)sender 
{
    [self performSegueWithIdentifier:@"SegueTitle"];
}

按照prepareForSegue中的说明将数据对象添加到目标视图控制器中,您将处于良好状态.然后使用委托方法捕获从模板返回的所有数据(只需将数据作为属性添加到控制器中,您应该会很高兴)

Add your data object to the target view controller as noted in prepareForSegue and you will be in good shape. Then use the delegate method to catch any data returned from your template (just add the data as properties to the controller and you should be golden)

您可以在Xcode的实用程序项目模板中看到一个更好的委派示例(我刚刚键入了此代码.)希望这些信息对您有所帮助.您可以在这些资源上获得更多信息,也可以通过在Google和SO中搜索iOS授权来获得更多信息:

You can see a better example of this delegation in a utility project template from Xcode (I just keyed this in..) I hope this information helps. You can get more information at these resources and also by searching Google and SO for iOS delegation :

目标C中的概念(代表和数据源)

可可核心竞争力

这篇关于使用AppDelegate来回传递数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆