Objective-C:需要帮助理解为什么两种方法在以两种不同的方式访问UIView时反应不同



我在两天内问三个问题感觉很糟糕,但我被困住了,在论坛上搜索我找不到答案,所以我希望有人可以帮助我 - 我想这些都是学习乐趣的一部分!

在我的程序中,我有三个视图,它们按GridScreen -> GameScreen -> CorrectScreen的顺序排列。在正确屏幕上,我有一个按钮,可以返回到网格屏幕。

在网格屏幕上,我有一堆按钮,用户可以按下这些按钮进入游戏屏幕。当用户正确回答问题时,他将从游戏屏幕带到正确屏幕进行确认,然后返回网格屏幕。

上一个问题中,我问如何跟踪在 GridScreen 上按下的按钮,以便当我从 CorrectScreen 返回它时,我可以用勾号替换图标。这在之前已经解决了,但这样做我创造了另一个问题。

在 CorrectScreen 中,当用户按下按钮返回时,将调用以下两个函数:

[self.gridScreen updateUserIcon:buttonThatWasPressed];
[self.gridScreen updatePoints:accumulatedpoints];

其中 updateUserIcon 是:

-(void)updateUserIcon:(UIButton *)button
{
UIButton *buttonPressed = button; 
self.button1 = buttonPressed;
[self.button1 setImage:[UIImage imageNamed:@"tick.png"] forState:UIControlStateNormal];
}

和更新点是:

-(void)updatePoints:(int)points
{
    self.currentPoints.text = [[NSString alloc]initWithFormat:@"Current points: %d", points];
}

其中 button1 是 UIButton,currentPoints 是 UILabel。

现在,当我在调用这两个函数后使用以下代码返回 GridScreen 时,勾号出现在我想要的按钮上,但标签没有正确更新:第一种情况:

[[[self presentingViewController]presentingViewController] dismissModalViewControllerAnimated:YES];

而如果我以另一种方式使用,勾号根本不会出现,但标签会完美更新:第二种情况:

GridScreen *screen = [[GridScreen alloc] initWithNibName:nil bundle:nil];
screen.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:screen animated:YES];

(我通常使用第二种情况加载视图)。

在第一种情况下,即使我执行了以下代码:

-(void)updatePoints:(int)points
{
    self.currentPoints.text = @"A";
    NSLog(@"Current Points %@", self.currentPoints.text);
}

我的 NSLog 返回当前点数(空)。

解决方案与我返回 GridScreen 的第一种方法有关,我实际上并没有再次加载视图,但在第二种方法中我这样做了 - 但我无法理解我需要做什么才能正确更新分数和刻度。

如果有人可以提供帮助,我很想知道 - 我对使用Objective-C编程相当陌生,所以如果其中任何一个是"糟糕的代码",我很高兴被告知出了什么问题,所以我不会犯类似的错误。

再次感谢大家,这个网站非常适合提供帮助,提前感谢您的建议。

安 迪。

好吧,愚蠢的问题,但是您为什么不只使用通知来向屏幕发送消息?

这是最简单、最安全的方法。

在网格屏幕中添加以下通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(toggleLabel:) name:@"CorrectAnswerNotification" object:nil];

在按下新屏幕之前。

现在,在 CorrectScreen 中,在弹出视图之前触发该通知:

[[NSNotificationCenter defaultCenter] postNotificationName:@"CorrectAnswerNotification" object:self userInfo:nil];

在userInfo字典中传递您想要的任何信息(这可以是一个字典,因此您可以传递所需的任何信息)

在 GridScreen 中,使用 toggleLabel 方法管理所有内容:

-(void)toggleLabel:(NSNotification *)notification {
    //read the documentation dictionary
    NSDictionary *infoDictionary = [notification userInfo];
    //remove the notification first
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"CorrectAnswerNotification" object:nil];
    //now change the buttons...
    [self updateUserIcon:buttonThatWasPressed];
    [self updatePoints:accumulatedpoints];
}

因为我被问及通知中心,所以以下是直接来自 Apple 文档的一些详细信息:

NSNotificationCenter 对象(或简称通知中心) 提供在节目内广播信息的机制。一 NSNotificationCenter 对象本质上是一个通知调度 桌子。

对象向通知中心注册以接收通知 (NSNotification objects) 使用 addObserver:selector:name:object: 或 addObserverForName:object:queue:usingBlock: 方法。每 此方法的调用指定一组通知。因此 对象可以通过以下方式注册为不同通知集的观察者 多次调用这些方法。

当对象(称为通知发件人)发布 通知,它将 NSNotification 对象发送到通知 中心。然后,通知中心会通知任何观察者 通知符合注册时指定的标准 向他们发送指定的通知消息,传递 通知是唯一的论据。

通知

中心维护一个通知调度表,该表是 指定特定观察者的通知集。通知 set 是发布到通知的通知的子集 中心。每个表条目包含三个项目:

Notification observer: Required. The object to be notified when qualifying notifications are posted to the notification center.
Notification name: Optional. Specifying a name reduces the set of notifications the entry specifies to those that have this name.
Notification sender: Optional. Specifying a sender reduces the set of notifications the entry specifies to those sent by this object.

最新更新