我试图在一个uitableview中访问一个刷新控件方法,该方法位于导航控制器内部,这是一个tabbarcontroller,这是我的根,但我很难得到一个精确的句柄。
到目前为止,这是我在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];
任何帮助都会非常感激,因为我无法在网上找到任何这样的访问权限。
答案 0 :(得分:6)
如果您需要在不相关的对象之间进行通信,我认为最好的选择是使用NSNotifications。这允许您使用单例对象[NSNotificationCenter defaultCenter]
将通知从一个对象传递到另一个对象(或许多其他对象)。
因此,您可以将AppDelegate对象(或其他对象)观察特定通知,然后在需要刷新控件时使用tableviewController发布通知。
在app delegate类中,您可以添加观察者,如:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(forceDownload)
name:@"ForceDownloadNotification"
object:nil];
并且,在tableviewController中,您可以发布de通知,如:
[[NSNotificationCenter defaultCenter] postNotificationName:@"ForceDownloadNotification"
object:self];
在这里,我使用名称“ForceDownloadNotification”作为通知的名称。您可以使用所需的名称,但为了使此解决方案正常工作,您必须在开始观察时和发布通知时使用相同的名称。
Here你有关于这个主题的教程。
答案 1 :(得分:3)
我喜欢路易斯·埃斯皮诺萨的方法,但这并没有回答本身的问题。
如果要调用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(或子类)中设置refreshcontrol就像你问的那样:
- (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,因为它更简单,但这并不意味着我们无法按照您最初计划的方式访问对象。
(如果你想要示例代码请求它。)
问候。
答案 2 :(得分:0)
如果你的目标确实只是让你的刷新控制与networkActivityIndicator同步,那么一个选项就是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];
}
}