【问题标题】:View not updating in tabbar app在标签栏应用程序中查看未更新
【发布时间】:2011-01-29 16:11:14
【问题描述】:

我一直在开发一个标签栏应用程序,它有一个让我难过的错误(仍然)。

当我进入一个新选项卡时,存储在应用程序模型部分中的数据不会被视图使用,因此会显示陈旧的信息(图表、数字等)。我尝试了两种强制更新的方法,由[self updateDisplay] 在视图中处理。 (1)在app delegate中,使用UITabBarControllerDelegate方法判断选择了哪个tab,然后给它发送更新消息。这是委托方法的一部分:

if (viewController == [tabBarController.viewControllers objectAtIndex:1]) {
    NSLog(@"graphViewController selected, graphViewController = %@", graphViewController);
    [graphViewController updateDisplay];                    
}

这是我想做的工作的方式。然而,显示并没有更新,尽管 NSLog 确认 updateDisplay 已经触发。

(2) 通过执行[self updateDisplay],在视图中按下按钮以更新显示。这有效,但并不令人满意。有趣的来了。在下面的日志中,我们看到(1)委托方法被调用,(2)graphViewController被选中,(3)graphViewController的updateDisplay方法被调用。伟大的!但是此时barGraph 为空,并且包含从ourLog 中的浮点数读取的标签的显示不会更新。对象ourLog 是模型的一部分,它与“磁盘”上的文件同步。 (barGraph 更新自 ourLogupdateDisplay)。

继续前进,我们现在在由 GraphViewController 管理的视图中,我们按下“测试”按钮 (6),updateDisplay 被调用,视图正确更新。

请注意,在 1--5 中,GraphViewController 位于 0x4e346e0,而在 6--9 中,它位于 0x4b53c80。如果你来回切换,切换和切换,按下“测试”按钮,你总是会得到十六进制数字。起初我认为不知何故有两个GraphViewController 的实例漂浮在周围。但是我覆盖了该类的 init 方法以便记录它。它只出现一次。所以我完全被难住了。

-- 吉姆

  • 1] 调用 UITabBarControllerDelegate 方法,self =
  • 2] 选择graphViewController,graphViewController =
  • 3] GraphViewController,updateDisplay 调用,self =
  • 4] 我们的日志:
  • 5] updateDisplay, barGraph: (null)
  • 6] 测试推送
  • 7] GraphViewController,updateDisplay 调用,self =
  • 8] 我们的日志:
  • 9] 更新显示,条形图:>

PS。我最初在UIVIew subclass object becomes mysteriously nil in tabbar app 发布了这个。我重新发布这个问题是因为问题更普遍,barGraph 在应用程序生命周期的各个阶段为空。不知何故,当我调用它时需要访问的东西不是,所以我必须找出一种不同的方式来调用它。但它并没有消失(我也覆盖了dealloc,并没有发现barGraph 曾经发布过)。

附录 1:条形图。

这是在 GraphViewController 中创建 barGraph 的方式:

@interface GraphViewController : UIViewController {

BarGraph *barGraph;

}

@property (nonatomic, retain) BarGraph *barGraph;

@property (nonatomic, retain) IBOutlet UIButton *testButton;

- (void) updateDisplay;
- (IBAction) testAction: (id) sender;

@end

@implementationviewDidLoad alloc-inits barGraph:

- (void) viewDidLoad {
    [super viewDidLoad];
    NSLog(@"xx:BARGRAPH: alloc-init in viewDidLoad, GraphBar");
    barGraph = [[BarGraph alloc] initWithFrame:CGRectMake(15, 140, 289, 130)];
    [self.view addSubview:barGraph];    
    [self updateDisplay];
}

最后,这里是updateDisplay的实现:

- (void) updateDisplay {

    // Check to see where GraphViewController is:
    NSLog(@"GraphViewController, updateDisplay called, self = %@", self);

    // Get a pointer to the current data to graph
    Log *ourLog = [self theDelegate].currentLog

    // Log info
    NSLog(@"ourLog: %@", ourLog);
    NSLog(@"updateDisplay, barGraph: %@", self.barGraph);

    // Get the current data out of ourLOg
    self.barGraph.data = ourLog.log;
    // And ask barGraph to display it
    [barGraph setNeedsDisplay];
}

附录 2:viewWillAppear。

我将viewWillAppear添加到GraphViewController.m如下:

- (void) viewWillAppear:(BOOL)animated
{
     NSLog(@"xx: GraphViewController, viewWillAppear has fired");
     [super viewWillAppear:animated];
     [self updateDisplay];
}

这似乎是正常和最佳的解决方案,但 viewWillAppear 永远不会触发。注意方法testAction,通过按钮激活:

- (IBAction) testAction: (id) sender {
    NSLog(@"test pushed");
    [self updateDisplay];
}

按下已连接的按钮以正确更新显示。但我当然希望 iOS 按下按钮,而不是我:-)

【问题讨论】:

    标签: iphone cocoa-touch uiviewcontroller uitabbarcontroller


    【解决方案1】:

    管理该选项卡的 UIViewController 应该引用您的自定义 UIView。在你的 UIViewController 的 -viewWillAppear 方法中,你可以调用 -updateDisplay。我假设 barGraph 是对您的自定义视图的引用。如果您在 xib 中创建它,只需确保将其连接到您的 IBOutlet 并且该插座的 @property 设置为保留。如果您没有在 xib 中创建 barGraph,那么我假设您是在 viewDidLoad 中创建它。无论哪种方式,请确保将其设置为您的 @property。

    如果你不是以任何一种方式创建它,那么你是如何创建它的?

    【讨论】:

    • 嗨,我正在以编程方式在 GraphViewController 中创建 barGraph 的实例(barGraph 是我在其他应用程序中使用的自定义视图)。我已经在附录 1 中发布了上面的一些相关代码。我也尝试过 viewWillAppear,但它似乎永远不会被调用。我会再看看这个。谢谢!
    • 我根据上面的附录 2 插入了 viewWillAppear。唉,它永远不会着火。如果我能做到这一点,这可能会解决我的问题。
    • 我可以通过从 UITabBarDelegate 方法调用它来手动触发它——但是当 GraphViewController 的 viewWillAppear 触发,随后调用 updateDisplay 时,老问题是以稍微不同的方式创建的。我相信iOS必须调用这个方法。
    • 我发现了这个:stackoverflow.com/questions/1650545/… 并检查了它。类名在 IB 中正确设置。还是被难住了!
    • 也许这就是为什么viewWillAppearviewDidAppear 不会触发:stackoverflow.com/questions/2308985/…(“技术上视图仍然可见”,即在另一个视图后面)。如果是这样,那么我将不得不寻找另一种解决方案来让updateDisplay 在正确的时刻开火。因为它在通过按下按钮手动激活时确实有效,但在选择新选项卡时从代表调用时无效。嗯!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 2013-04-01
    相关资源
    最近更新 更多