我喜欢 MVC,但我并不是一个绝对的纯粹主义者,以至于为了完成一项相当琐碎的任务而伤害自己,所以您在这里得到的答案是好的和有用的。但是,通过创建 ivar 来引用特定类型(例如标签或其他视图控制器),您可以将不需要耦合的事物耦合在一起。您可以做的就是使您的第一个选项卡视图控制器成为第二个选项卡视图控制器的委托。因此,在您的应用程序委托中执行类似的操作。
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