查看未在选项卡栏应用程序中更新

发布于 2024-10-14 19:09:54 字数 3935 浏览 0 评论 0原文

我一直在开发一个标签栏应用程序,该应用程序有一个错误让我感到困惑(仍然)。

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

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 是通过 updateDisplayourLog 更新的)。

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

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

-- Jim

  • 1] UITabBarControllerDelegate 方法被调用,self =
  • 2] graphViewController 选择,graphViewController =
  • 3] GraphViewController,updateDisplay 被调用,self =
  • 4] ourLog:
  • 5] updateDisplay,barGraph:(null)
  • 6] 测试推送
  • 7] GraphViewController,updateDisplay 被调用, self =
  • 8] ourLog:
  • 9] updateDisplay, barGraph: >

附言。我最初将其发布于 UIVIew 子类对象在选项卡栏应用程序中神秘地为零。我重新发布这个问题是因为这个问题更普遍,barGraph 在应用程序生命周期的各个点都为空。不知何故,当我调用它时需要访问的东西却无法访问,所以我必须找出一种不同的方式来调用它。但它并没有消失(我也覆盖了dealloc并且没有发现barGraph被释放)。

附录 1:BarGraph。

以下是在 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

@implementation 中,viewDidLoad 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 按下按钮,而不是我:-)

I've been working on a tabbar app that has a bug that has me stumped (still).

When I move into a new tab, data stored in the model part of the app is not used by the view, which thus displays stale info (a graph, numbers, etc.). I've tried two ways of forcing an update, which is handled in the view by [self updateDisplay]. (1) In the app delegate, use the UITabBarControllerDelegate method to determine which tab is selected, then send it an update message. Here is a piece of the body of the delegate method:

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

This is the way I would like to do the job. However, the display is not updated, though NSLog confirms that updateDisplay has fired.

(2) Press a button in the view to update the display by executing [self updateDisplay]. This works, but is not satisfactory. Now comes the fun part. In the log below, we read (1) the delegate method is called, (2) the graphViewController is selected, and (3) the graphViewController's updateDisplay method is called. Great! But barGraph is null at this point, and the display including labels that are read from floats in ourLog is not updated. The object ourLog is part of the model and it is synchronized with a file on "disk". (barGraph is updated from ourLog via updateDisplay).

Moving on, we are now in the view managed by GraphViewController, we push the "test" button (6), updateDisplay is called, the view is properly updated.

Notice that in 1--5, GraphViewController was at 0x4e346e0, whereas in 6--9 it was at 0x4b53c80. If you toggle back and forth, tabbing out and in, pressing the "test" button, you always get the hex numbers. At first I thought that somehow there were two instances of GraphViewController floating around. But I overrode that class's init method so as to log it. It only shows up once. So I am totally stumped.

-- Jim

  • 1] UITabBarControllerDelegate method called, self =
  • 2] graphViewController selected, graphViewController =
  • 3] GraphViewController, updateDisplay called, self =
  • 4] ourLog:
  • 5] updateDisplay, barGraph: (null)
  • 6] test pushed
  • 7] GraphViewController, updateDisplay called, self =
  • 8] ourLog:
  • 9] updateDisplay, barGraph: >

PS. I originally posted this at UIVIew subclass object becomes mysteriously nil in tabbar app. I'm posting this anew because the problem is more general that barGraph being null at various points in the apps lifecycle. Somehow stuff that needs to be accessible when I call it is not, so I have to figure out a different way to call it. But it doesn't disappear (I also overrode dealloc and didn't find that barGraph was ever released).

Addendum 1: BarGraph.

Here is how barGraph is created in GraphViewController:

@interface GraphViewController : UIViewController {

BarGraph *barGraph;

}

@property (nonatomic, retain) BarGraph *barGraph;

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

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

@end

In @implementation, viewDidLoad 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];
}

Finally, here is the implementation of 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];
}

Addendum 2: viewWillAppear.

I added viewWillAppear to GraphViewController.m as follows:

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

This would seem like the normal and best solution, but this viewWillAppear never fires. Note the method testAction, which is activated by a button:

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

Pushing the button that it is wired to properly updates the display. But of course I want iOS to push the button, not me:-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

眸中客 2024-10-21 19:09:54

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

如果您不以任何方式创建它,那么您将如何创建它?

The UIViewController that manages that tab should have a reference to your custom UIView. In your UIViewController's -viewWillAppear method, you can call -updateDisplay. I'm assuming that barGraph is the reference to your custom view. If you are creating it in your xib, just make sure you hook it up to your IBOutlet and that your @property for that outlet is set to retain. If you aren't creating barGraph in your xib then I assume you are creating it in your viewDidLoad. Either way, make sure you set it to your @property.

If you aren't creating it either way, then how are you creating it?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文