访问另一个视图控制器中的实例方法

发布于 2024-10-10 17:31:54 字数 641 浏览 1 评论 0原文

我有一个带有 4 个选项卡的选项卡栏控制器。每个选项卡都有自己的视图控制器和 UIWebView。

假设我在 vc1 中有一个按钮 (button1),还有一个实例方法 onClick1。在 vc2 中,我有一个名为 reload 的方法。我的问题是,如何从 vc1 访问 vc2 中的特定实例方法 onClick1?

为了获得更多细节,我实际上正在尝试为 iPhone 编写一个简单的购物实用程序。当用户从浏览视图将商品添加到购物车时,我希望能够自动重新加载购物车视图。

下面是我的意思的一些例子。这个问题比我想象的要困难。我不确定我是否重新设计了我的应用程序或什么。也许 vc1 和 vc2 都属于 vcmain 的子类并且在那里引用它们中的每一个?但是,如果我这样做,那么我如何将它们引用到相应的 .xib?谢谢你们!

@implementation viewController 1

//Reloads vc2
-(IBAction) onClick1: (id) sender {

 //Calls vc2 reload
 [vc2 reload];
 }

@end

@implementation viewController 2

//Reload View
-(void)reload {
  [webView reload];
}

@end

I have a tab bar controller with 4 tabs. Each tab has its own view controller and a UIWebView.

Let's say I have a button (button1) in vc1 and an instance method onClick1 as well. In vc2 I have a method named reload. My question is, how do I access the specific instance method, onClick1 in vc2, from vc1?

For further detail, I'm actually trying to code a simple shopping utility for the iPhone. When a user adds an item to the cart from the browse view, I want to be able to automatically reload the cart view.

Below are some examples of what I mean. This problem has been more difficult than I thought. I'm not sure if I have redesign my application or what. Perhaps have both vc1 and vc2 belong to a subclass of vcmain and have reference to each of them there? However, if I do that, then how do I refer them to their corresponding .xib? Thanks guys!

@implementation viewController 1

//Reloads vc2
-(IBAction) onClick1: (id) sender {

 //Calls vc2 reload
 [vc2 reload];
 }

@end

@implementation viewController 2

//Reload View
-(void)reload {
  [webView reload];
}

@end

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

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

发布评论

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

评论(2

此岸叶落 2024-10-17 17:31:54

基本上可以采用三种方法,每种方法都有优点和缺点。我将为您提供一个高级概述,并让您访问 Apple 相当全面的文档以了解详细信息。希望我能为您提供正确的谷歌条款以获取更具体的帮助。

@dredful 非常巧妙地详细描述的方法是拥有“其他”视图控制器的句柄并直接调用它们的方法。这工作得很好,但是将指针传递给周围的所有控制器可能会令人困惑和麻烦,并且遍历视图层次结构以获取所需的控制器确实非常棘手。

第二种方法是键值观察。您可以注册一个视图控制器来“监视”另一个视图控制器的特定键(命名属性),并在发生各种情况时触发特定选择器。这有点神奇而且很好,尽管在某些时候你必须同时拥有指向两个控制器的指针,这并不能完全缓解上面“直接调用”方法的缺点。这也是视图控制和数据的一种不幸的耦合,有点破坏 MVC。

第三种方法是使用 NSNotificationCenter。类可以发布通知,并且任何其他注册自身以侦听此类通知的对象都可以在发生这种情况时被触发。这很好,因为您可能有很多不同的对象向购物车添加商品,它们只需向通知中心发送一条注释(如果需要,甚至可以向其传递一个对象或任意数据),并且购物车视图可以使用这些通知,抓住传递的对象,并做它的事情,而不特别关心谁在和它说话。它使应用程序的各个部分保持良好的解耦。缺点是,它有一点开销,并且通知消费类执行的任何选择器都是同步发生的,因此您无法隐藏网络活动或其他一些长进程。

You've basically got three approaches, each one of which has plusses and minuses. I'm going to give you a high-level overview and let you go to Apple's quite comprehensive documentation for details. Hopefully I can give you the right terms to google for more specific help.

The approach that @dredful quite ably details is to have a handle to the "other" view controller(s) and call methods on them directly. That works fine, but it can be confusing and cumbersome handing pointers to all your controllers around, and traversing the view hierarchy to get get at the controller you want can be very tricky indeed.

The second approach is Key-Value Observing. You can register one view controller to "watch" a particular key (named property) of another view controller, and fire a particular selector when various things happen with it. This is kind of magical and nice, although at some point you have to have pointers to both controllers at the same time, which doesn't entirely relieve the downside of the "call it directly" method above. It is also a sort of unfortunate coupling of view control and data, kind of breaks MVC.

The third approach is using NSNotificationCenter. A class can post a notification, and any other object that registers itself to listen for that sort of notification can be triggered when that happens. It's nice because you might have LOTS of different objects adding items to the cart, and they can just shoot the notification center a note (even passing it an object or arbitrary data, if it wants), and the cart view can consume those notifications, catch the passed objects, and do its thing, not caring in particular who's talking to it. It keeps separate pieces of your application nicely decoupled. The downside is, it's got a bit of overhead to it, and whatever selector the notification-consuming class performs happens synchronously, so you can't hide network activity or some other long process there.

给不了的爱 2024-10-17 17:31:54

我认为您应该已经拥有类似基本 UIViewController (我们称之为 MyTabBars)之类的东西,它有一个包含您所有选项卡的 UITabBarController *tabBarController栏视图控制器。如果这听起来很熟悉,您将需要 MyTabBars 中的一个名为 -(void)reloadCart 的方法。 reloadCart 将遍历 tabBarController.viewControllers 数组。在每个 viewController 上,您可以执行 respondsToSelector:@selector(reload),如果特定的 viewController 符合条件,则它会调用该选择器方法。

为了做到这一点,您可能希望所有 vc1、vc2、... 文件都定义并合成一个 id delegate。当 MyTabBars 创建不同的选项卡栏时,它将 vc1 和 vc2 delegate 设置为 self

@implementation MyTabBars

//Reload Cart View
-(void)reloadCart {
  for (UIViewController *thisUIViewController in tabBarController.viewControllers){
     if ([thisUIViewController respondsToSelector:@selector(reload)]) {
         [thisUIViewController reload];
     }
  }
}

@end

假设您知道如何将 MyTabBars 委托传递到 vc1 和 vc2 中,那么您现在可以在 vc1 中使用以下代码:

@implementation viewController1

//Reloads vc2
-(IBAction) onClick1: (id) sender {

 //Calls MyTabBars reloadCart which will look for all tab bar view controllers
 //that have the 'reload' method
 [delegate reloadCart];
 }

@end

此解决方案的想法将导致 MyTabBars 触发任何 重新加载 在我们的任何选项卡栏视图控制器中找到的方法。因此,在 vc1、vc2 等文件中命名此类方法时要小心。此解决方案将触发唯一的 vc 方法或具有相同方法的多个 vc,具体取决于您的命名约定。

希望这有帮助。

I'm thinking you should already have something like a base UIViewController (let's call it MyTabBars) that has a UITabBarController *tabBarController containing all your Tab Bar View Controllers. If that sounds familiar, you will want a method in MyTabBars called -(void)reloadCart. reloadCart will walk the array of tabBarController.viewControllers. On each viewController you can perform a respondsToSelector:@selector(reload) and if the specific viewController qualifies then it calls that selector method.

In order to do this you probably want all your vc1, vc2, ... files to have an id delegate defined and synthesized. When MyTabBars creates the different tab bars it sets the vc1 and vc2 delegate to self.

@implementation MyTabBars

//Reload Cart View
-(void)reloadCart {
  for (UIViewController *thisUIViewController in tabBarController.viewControllers){
     if ([thisUIViewController respondsToSelector:@selector(reload)]) {
         [thisUIViewController reload];
     }
  }
}

@end

Assuming you know how to pass a delegate of MyTabBars into your vc1 and vc2, then you can now have the following code in vc1:

@implementation viewController1

//Reloads vc2
-(IBAction) onClick1: (id) sender {

 //Calls MyTabBars reloadCart which will look for all tab bar view controllers
 //that have the 'reload' method
 [delegate reloadCart];
 }

@end

This solution idea will cause MyTabBars to trigger any reload method found in any of our tab bar view controllers. Therefore be careful with the naming of such a method in your vc1, vc2, etc files. This solution will trigger a unique vc method or multiple vcs with the same method depending on your naming convention.

Hope this helps.

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