1

好的,在进行网络通话后,我正在尝试刷新每个选项卡的选项卡内容,并且我尝试了很多不同的方法来做到这一点,但我已经记不清了。有人可以告诉我这是怎么可能的吗?

Web 调用只是从服务器调用 JSON 并使用它来更新选项卡的内容。出于测试目的,我在设置类中设置了一个按钮。设置类是主页选项卡中的一个视图,其中有一个名为刷新的按钮。单击此按钮时,设备上存储的 JSON 与应用程序启动时从 Web 调用中调用的不同。这让我不必更改服务器上的 JSON。

我将带您了解我尝试过的一些技术,如果有人能告诉我我做错了什么,我将不胜感激。

我尝试制作一个类的实例并像这样调用刷新方法

DashboardVC *db = [[DashboardVC alloc] init];
[db refreshMe];

仪表板类中的刷新方法是这样的

-(void) refreshMe
{     
     [self loadView];
     [self viewDidLoad];
}

然而没有运气。如果我在 Dashboard 类中调用它,此方法将起作用,但如果我从另一个类调用它,则不会起作用。我认为它已经成为我正在实例化一个新类并调用它的刷新。所以我放弃了这种技术并转向下一个方法

这会遍历所有 tabBars 并更改 tabTitles 没有任何问题,所以我知道它肯定会正确循环 ViewControllers。

我还尝试了各种视图方法,如 ViewDidAppear、viewWillAppear 等,但没有运气。

我还尝试像这样通过 tabController 访问我在 dashBoard 类中创建的 refreshMe 方法

[[[self.tabBarController viewControllers] objectAtIndex:0] refreshMe];

但同样没有运气,这只会导致我的应用程序崩溃。

我通读了本指南

https://developer.apple.com/library/ios/#documentation/WindowsViews/Conceptual/ViewControllerPGforiOSLegacy/TabBarControllers/TabBarControllers.html

在苹果网站上,但似乎没有涵盖如何刷新单个标签内容。

我只想让每个单独的选项卡在进行网络通话后刷新其内容,并且花了很长时间试图弄清楚这一点,但没有任何效果。

如果有人能告诉我我做错了什么,我将不胜感激?

提前谢谢....

编辑:

扩展我尝试过的内容

在与 Michael 讨论后,我意识到您永远不应该根据 Apple 指南调用 loadView。所以我删除了对 LoadView 的所有引用。我现在在所有主要的 ViewController 中放置了一个名为 RefreshMe 的方法,它在类中设置视图、图像文本等。而这个方法是放在ViewDidLoad里面的。现在我希望能够在发生网络调用后调用这些方法,从而有效地刷新应用程序。

我的 viewDidLoad 现在在我所有的主要课程中看起来都是这样的。

- (void) viewDidLoad {
     [super viewDidLoad];
     [self refreshMe];
}  

然后 refreshMe 方法包含设置屏幕的代码。

从 Web 调用中提取的 JSON 数据将设置 5 个选项卡中每个选项卡的内容,因此需要在 Web 调用后将它们全部刷新。

我尝试遍历 viewControllers 并调用 viewDidLoad,这又应该调用设置类的 refreshMe 方法,但是没有任何反应。我使用的代码是这个

NSArray * tabBarViewControllers = [self.tabBarController viewControllers];

for(UIViewController * viewController in tabBarViewControllers)
{
    [viewController viewDidLoad];
}

暂时我也包括了

NSLog(@"Method called"); 

在每个类的 viewDidLoad 中测试它是否被调用。但是,仅当我第一次加载应用程序或重新输入应用程序时才会打印出该消息。在我单击设置屏幕中的刷新按钮后应该调用此方法,但它不是,我不知道为什么。

任何人都知道为什么这不起作用?

4

2 回答 2

1

与其在更新标签栏顺序时刷新视图控制器,不如通过实现子类 UIViewController 的方法在视图出现之前简单地刷新视图viewWillAppear:

这意味着每次您的视图即将出现时,您都可以更新视图以获取新的和更新的内容。

于 2012-05-18T12:40:21.040 回答
1

从问题和您的评论来看,听起来至少有两个问题:

  1. 您无法访问由应用的标签栏控制器管理的视图控制器。

  2. 您似乎正在违反视图控制器的正常操作。

第一部分应该很容易整理。如果您有一个指向对象的指针,您可以向该对象发送消息。如果相应的方法没有执行,那么要么指针没有指向你认为它执行的位置,要么对象没有你认为它执行的方法。让我们看看你的代码:

NSArray * tabBarViewControllers = [self.tabBarController viewControllers];

for(UIViewController * viewController in tabBarViewControllers)
{
    [viewController viewDidLoad];
}

此代码应该调用-viewDidLoad由某个选项卡栏控制器管理的每个视图控制器。暂时搁置这样做的智慧,我们可以说如果 self.tabBarController指向您认为的对象,则该代码应该按预期工作。您没有说此代码存在于您的应用程序中的什么位置——它是您的应用程序委托的一部分、由相关选项卡栏控制器管理的视图控制器之一的一部分,还是其他地方?使用调试器单步执行代码。在第一行之后,是否tabBarViewControllers包含视图控制器数组?视图控制器的数量是否正确,它们是否属于预期类型?如果-viewDidLoad您的视图控制器的方法没有被调用,那么答案肯定是“不”,所以找出self.tabBarController原因

现在,绝对值得指出(正如迈克尔所做的那样)你-viewDidLoad一开始就不应该跟注。视图控制器将在创建视图后将该方法发送给自己(从 .xib/storyboard 文件加载或以编程方式创建)。如果你调用-viewDidLoad自己,它要么在视图创建之前运行,要么第二次运行,这些都没有帮助。

此外,尝试抢先“刷新”每个视图控制器的视图也没有多大意义。如果您的应用程序正在从 Web 服务(或其他任何地方)检索一些数据,它应该使用结果数据来更新其模型,即应用程序管理的数据对象。选择视图控制器时,标签栏控制器将显示其视图,并且视图控制器的-viewWillAppear方法将在视图显示之前被调用。使用该方法从模型中获取您需要的数据并更新视图。这样做,你知道:

  • 视图控制器的视图已经被创建

  • 视图中显示的数据将是最新的,即使其他视图控制器之一修改了数据

  • 您永远不会花时间更新用户可能永远不会查看的视图

同样,如果用户可以对显示的数据进行任何更改,则应确保在进行更改时或在视图控制器的-viewWillDisappear方法中更新模型,以便下一个视图控制器可以使用正确的数据。

于 2012-05-21T09:53:33.783 回答