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

时间:2012-06-03 23:26:01

标签: objective-c uiview presentmodalviewcontroller

我在两天的时间里问三个问题我感觉很糟糕,但我陷入困境并且在论坛上搜索我找不到答案所以我希望有人可以帮助我 - 所有这些都是我学习的乐趣!

在我的程序中,我有三个视图按GridScreen顺序排列 - > GameScreen - > CorrectScreen。在CorrectScreen上,我有一个返回GridScreen的按钮。

在GridScreen上我有一堆按钮,用户可以按这些按钮进入GameScreen。当用户正确回答问题时,他将从GameScreen获取到CorrectScreen进行确认,然后返回到GridScreen。

在之前的一个问题中,我问过如何跟踪在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];
}

和updatePoints是:

-(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返回当前点(null)。

该解决方案与我的第一个返回GridScreen的方法有关我实际上并没有再次加载视图,而是在我做的第二种方法中 - 但我无法理解我需要做什么来获得两个分数正确更新和勾选。

如果有人可以提供帮助,我很想知道 - 我对使用Objective-C进行编程是相当新的,所以如果其中任何一个是“坏代码”,我很高兴被告知出了什么问题所以继续我不做类似的错误。

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

安迪。

1 个答案:

答案 0 :(得分:0)

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

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

在GridScreen中添加此通知:

[[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 Documentation的详细信息:

  

NSNotificationCenter对象(或简称为通知中心)   提供了一种在程序中广播信息的机制。一个   NSNotificationCenter对象本质上是一个通知分派   表

     

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

     

当对象(称为通知发件人)发布时   通知,它会向通知发送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.