0

私のルートである tabbarcontroller から、navigationcontroller 内にある uitableview の更新制御メソッドにアクセスしようとしていますが、正確なハンドルを取得するのに問題があります。

これはこれまでの AppDelegate での私のコードですが、機能しません...

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

[0]、[1]、[2]、[3]を介してアクセスできると思われる5つのタブバーアイテムがあり、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

私はルイス・エスピノーザのアプローチが好きですが、それは質問自体には答えません。

アプリ デリゲートの rootViewController である UINavigationController 内にネストされた UITableViewController 内のメソッドを呼び出す場合。まず、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 を使用する方が簡単であることを好みますが、それは、最初に計画した方法でオブジェクトにアクセスできないという意味ではありません。

(サンプルコードが必要な場合は、それを求めてください)。

よろしく。

于 2013-04-03T20:49:01.813 に答える
0

あなたの目標が本当に更新コントロールをnetworkActivityIndi​​catorと同期させ続けることである場合、1つのオプションは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 に答える