如何从一个视图访问数据到另一个视图?

时间:2010-06-09 19:01:21

标签: iphone objective-c uiviewcontroller

我有一个UITabBarController,有两个标签:

  1. UINavigationController
  2. OptionsViewController : UIViewController
  3. 如何在UILabel.text中调用已在OptionsViewController调用的新添加模式视图中的UINavigationController中设置的数据(例如。{{1}})?

    编辑1:

    场景:启动应用程序后,我选择第二个名为“选项”的标签栏,我填写一个textField。标签设置为 textField 的值。接下来,我选择第一个名为“Main”的标签栏,其中有一个按钮。我点击按钮,出现新的模态视图。在这个新的模态视图中,我想显示 textField

    的值

4 个答案:

答案 0 :(得分:2)

我喜欢MVC,但我不是一个绝对的纯粹主义者,为了完成一个相当微不足道的任务而伤害自己,所以你在这里得到的答案是好的和有用的。但是,通过创建一个ivar来引用特定类型(如标签或其他视图控制器),您可以将不需要耦合的事物耦合在一起。你可以做的是让你的第一个标签视图控制器成为你的第二个标签视图控制器的委托。所以在你的app delegate中做这样的事情。

OptionsViewController *optionsViewController = // ... get this from the tab view
FirsTabViewController *firstTabViewController = // ... same here

[optionsViewController setDelegate:firsTabViewController];

这意味着您需要在OptionsViewController中使用ivar:

@property (assign) id delegate;

然后,当您想要触发更改的任何事件发生在选项视图控制器中时,请查看该委托是否可以响应您已命名的选择器。例如:

- (void)someEventHappenedLikeTyping:(id)sender;
{
    if ([delegate respondsToSelector:@selector(setOptionsString:)]
        [delegate performSelector:@selector(setOptionsString:) withObject:[label text]];
}

请注意,您从未指定任何特定的对象类型。您只需检查委托(声明为id)是否可以响应该选择器。如果它可以,它会按照它所说的去做,否则就是沉默。

为了使其正常工作,您需要在FirstTabViewController中为optionsString使用ivar,因此它将在标头中声明为:

@property (copy) NSString *optionsString;

然后在.m中@synthesize它。这会导致-setOptionsString成为一个有效的选择器,它将在-someEventHappenedLikeTyping方法中被调用。

无论如何,现在,如果您需要更改哪个视图控制器引用哪个,您不必进入标题并更改引用的ivar类型。您只需要在视图控制器中实现选择器(顺便说一下,这称为非正式协议),视图控制器是选项视图控制器的委托。

那里有一些值得思考的东西。希望有所帮助。可以在我添加的代码中进行进一步的解耦,但同样对于这样一个简单的任务来说可能有点过分。如果您需要澄清或想通过进一步解耦来理解我的意思,请告诉我。

致以最诚挚的问候,

P.S。 有时需要在两个标签栏视图控制器之间共享数据,这意味着您有设计缺陷。如果您想要从选项视图中存储首选项,则只需调用

即可
[[NSUserDefaults standardUserDefaults] setObject:[label text] forKey:@"option1"];
[[NSUserDefaults standardUserDefaults] synchronize];

然后您可以使用;

从主选项卡中拉回NSUserDefaults
NSString *option1 = [[NSUserDefaults standardUserDefaults] objectForKey:@"option1"];
// Do something with option1

答案 1 :(得分:1)

在OptionsViewController中,创建一个属性:

@property (nonatomic, retain) UILabel *mylabel;

然后在创建OptionsViewController之后,在显示之前,设置mylabel属性。 (或者您可能只想要文本,因此可以使用NSString*属性。)

修改

所以你可能想做这样的事情:

OptionsViewController *vc = [[OptionsViewController alloc] init];
vc.mylabel = mySomethingLabel;
[self presentModalViewController:vc animated:YES];

因此,在创建对象后,设置属性,然后显示视图控制器。

答案 2 :(得分:0)

我通常在每个viewcontrollers中设置IBOutlets,指向另一个控制器。 因此,如果我有视图控制器A和B.A有一个IBOutlet到B和B到A.然后每当我想从A访问B中的任何东西时,我只需在B上使用点运算符。

在您的示例中,UINavigationController将#include "OptionsViewController.h"并且具有ivar IBOutlet OptionsViewController * ovc(在IB中设置),然后您的选项视图控制器中的任何实例变量都可以从ovc.UILabel.text引用导航控制器。可以反转此过程以从选项视图控制器中的导航控制器访问值。

示例导航控制器(.h):

#include "OptionsViewController.h"
@interface UINavigationController // (whatever the name of this class is)
{
OptionsViewController * ovc;
}
@property (nonatomic, retain) IBOutlet OptionsViewController * ovc;
@end

示例OptionsViewController.h:

@interface OptionsViewController 
{
UILabel * label;
}
@property (nonatomic, retain) IBOutlet UILabel * label;
@end

然后从UINavigationController(.m)开始编写ovc.label.text来访问文本。

答案 3 :(得分:0)

我有一种简单的方法来访问视图之间的数据。我们试试吧。你有两个名为view1和view2的视图,你可以在view2.h中定义一个View * vc1属性,在弹出view2时将vc1指向view1,如下所示:

<强> view1.m

//here pop out view1 code
    View2 *view2 = [[View2 alloc] initWithNibName:@"View2" bundle:[NSBundle mainBundle]];
    [self.navigationController pushViewController:view2 animated:YES];
    view2.vc1 = self;  //transfer view1 instance to view2,use vc1 you may handle view1 in view2 directly
        [view2 release];

<强> view2.h

    #import "view1.h"
    @property (nonatomic, retain) IBOutlet View1 *vc1; //here you could name it as view1 as well :)

<强> view2.m

    vc1.lblTable.text = @"ok"; //you'll see "ok" in view1
    [self.navigationController popViewControllerAnimated:YES]; //navigate to view1

//不要忘记发布vc1