0

我试图从我的根标签栏控制器访问位于导航控制器内部的 uitableview 中的刷新控制方法,但我无法获得准确的句柄。

到目前为止,这是我在 AppDelegate 中的代码,但它不起作用......

UITableViewController *tableView = (UITableViewController *)[[self.tabbarController viewControllers][0] tableView];
    [tableView.refreshControl beginRefreshing];

我有 5 个标签栏项目,我相信我可以通过 [0]、[1]、[2]、[3] 和我在 UITableView 中的代码访问它们(尽管可能无关紧要)...

// Add Refresh Control
    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    [refreshControl addTarget:appDelegate action:@selector(forceDownload) forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refreshControl;
    [refreshControl release];

任何帮助将不胜感激,因为我找不到任何可以访问如此深入的在线。

4

3 回答 3

6

如果您需要在不相关的对象之间进行通信,我认为最好的选择是使用 NSNotifications。这允许您使用单例对象[NSNotificationCenter defaultCenter],将通知从一个对象传递到另一个对象(或许多其他对象)。

所以你可以把 AppDelegate 对象(或其他对象)放在观察一个特定的通知,然后在需要刷新控件时用 tableviewController 发布通知。

在应用程序委托类中,您可以添加观察者,例如:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(forceDownload)
                                             name:@"ForceDownloadNotification"
                                           object:nil];

而且,在 tableviewController 中,您可以发布通知,例如:

[[NSNotificationCenter defaultCenter] postNotificationName:@"ForceDownloadNotification" 
                                                    object:self];

在这里,我使用名称“ForceDownloadNotification”作为通知的名称。您可以使用所需的名称,但为了使此解决方案正常工作,您必须在开始观察和发布通知时使用相同的名称。

在这里你有一个关于这个主题的教程。

于 2013-04-02T15:09:00.913 回答
3

我喜欢 Luis Espinoza 的方法,但这本身并不能回答问题。

如果您想调用嵌套在 UINavigationController 中的 UITableViewController 中的方法,该 UINavigationController 是您的 App Delegate 的 rootViewController。首先,我们使用 UITableViewController(或子类)创建一个 navigationController:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

// Override point for customization after application launch.
CustomTableViewController *nuTableVC = [[CustomTableViewController alloc] initWithStyle:UITableViewStylePlain];
UINavigationController *nuNavController = [[UINavigationController alloc] initWithRootViewController:nuTableVC];
self.window.rootViewController = nuNavController;

[self.window makeKeyAndVisible];
return YES;
}

然后在你的 UITableViewController (或子类)中你设置刷新控件就像你问的那样:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Add Refresh Control
    UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
    [refreshControl addTarget:[[UIApplication sharedApplication] delegate]
                       action:@selector(forceDownload) 
             forControlEvents:UIControlEventValueChanged];
    self.refreshControl = refreshControl;
}

最后要访问 UItableViewController 您必须检查实例是否真的是您想要的类,这是我在您的App Delegate中创建的方法( forceDownload)的实现:

- (void)forceDownload {
NSLog(@"force download method in App Delegate");
UINavigationController *someNavController = (UINavigationController*)[_window rootViewController];

UIViewController *vcInNavController = [[someNavController viewControllers] objectAtIndex:0];

if ([vcInNavController isKindOfClass:[CustomTableViewController class]]) {
    NSLog(@"it is my custom Table VC");
    NSLog(@"here we can stop the refresh control, or whatever we want");
    CustomTableViewController *customTableVC = (CustomTableViewController *)vcInNavController;
    [customTableVC.refreshControl performSelector:@selector(endRefreshing)
                                       withObject:nil
                                       afterDelay:1.0f];
    }
}

我个人更喜欢使用 NSNotificationCenter 因为它更简单,但这并不意味着我们不能按照您最初计划的方式访问对象。

(如果您想要示例代码,请索取)。

问候。

于 2013-04-03T20:49:01.813 回答
0

如果您的目标确实是让您的刷新控制与 networkActivityIndi​​cator 同步,那么一个选项是 KVO。

在 viewController 中viewDidAppear:添加类似这样的内容

- (void)viewDidAppear:(BOOL)animated
{
  [super viewDidAppear:animated];

  UIApplication *application = [UIApplication sharedApplication];
  [application addObserver:self
                forKeyPath:@"networkActivityIndicatorVisible"
                   options:NSKeyValueObservingOptionNew
                   context:myContext];

  self.refreshControl.refreshing = [application isNetworkActivityIndicatorVisible];
}

然后确保在 viewController 不需要它时删除这个观察者 - 也许在viewDidDisappear:

- (void)viewWillDisappear:(BOOL)animated
{
  [super viewDidDisappear:animated];
  [[UIApplication sharedApplication] removeObserver:self
                                         forKeyPath:@"networkActivityIndicatorVisible"
                                            context:myContext];
}

现在开始实际工作

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context;
{
  if (myContext == context) {
    self.refreshControl.refreshing = [change[NSKeyValueChangeNewKey] boolValue];
  } else {
    [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  }
}
于 2013-04-02T15:36:37.807 回答