0

I feel bad asking three questions in the space of two days but I am stuck and searching the forum I couldn't find the answer so I hope someone can help me - all part of the fun of learning I suppose!

In my program I have three views which go in the order GridScreen -> GameScreen -> CorrectScreen. On the CorrectScreen I have a button which goes back to the GridScreen.

On the GridScreen I have a bunch of buttons which a user can press to go to the GameScreen. When the user answers the question correctly he is taken from the GameScreen to the CorrectScreen for acknowledgement and then back to the GridScreen.

In a previous question I asked how to track the button that was pressed on the GridScreen so that when I go back to it from the CorrectScreen I can replace the icon with a tick. That was solved earlier but by doing so I've created another problem.

In the CorrectScreen, when the user presses the button to go back the following two functions are called:

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

where updateUserIcon is:

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

and updatePoints is:

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

where button1 is a UIButton and currentPoints is a UILabel.

Now, when I go back to the GridScreen using the following code after calling the two functions the tick appears on the button I want, but the label does not update correctly: FIRST CASE:

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

whereas if I use this next way, the tick does not appear at all, but the label updates perfectly: SECOND CASE:

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

(I normally load views using the second case).

In the first case, even if I did the following code:

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

My NSLog returns Current Points (null).

The solution is something to do with my first method of going back to the GridScreen I don't actually load the view again but in the second method I do - but I cannot understand what I need to do to get both the score updating correctly and the tick.

If anyone can help I would love to know - I am fairly new to programming with Objective-C so if any of this is 'bad code' I am happy to be told what is wrong so going ahead I don't make similar mistakes.

Thanks again to you all, this site is fantastic for helping out and in advance I appreciate the advice.

Andy.

user1309044
  • 317
  • 3
  • 13
  • it sounds like your view hasn't properly loaded yet (set a breakpoint on "`viewDidLoad`" to be certain), which is why "`currentPoints` is a nil object. – Michael Dautermann Jun 03 '12 at 23:33
  • Hi Michael - maybe this answers your question - when I run viewDidLoad in the GridScreen part of the function sets the text of CurrentPoints - which in the initial case is 'Current Points: 0' as I would expect (NSLog confirms that). Of course, using the 'Case 1' method of going back to GridScreen, this doesn't call on viewDidLoad a second time. This means that in my question I'm actually setting self.currentPoints.text twice using the 2nd method as I'm setting it in viewDidLoad and in updatePoints, but that's just for illustration in the question, really. – user1309044 Jun 03 '12 at 23:47

1 Answers1

0

OK, silly question, but why aren't you just using Notifications to message the screens?

It's the easiest and safest approach.

In the GridScreen add this notification:

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

before pushing the new screen.

Now in the CorrectScreen, fire that notification before poping the view:

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

Pass any information you want in the userInfo dictionary (this can be a dictionary so you can pass along any information's you need)

And in the GridScreen manage everything in the toggleLabel method:

-(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];

}

Because I was asked about the Notification Center, here are some details straight from Apple Documentation:

An NSNotificationCenter object (or simply, notification center) provides a mechanism for broadcasting information within a program. An NSNotificationCenter object is essentially a notification dispatch table.

Objects register with a notification center to receive notifications (NSNotification objects) using the addObserver:selector:name:object: or addObserverForName:object:queue:usingBlock: methods. Each invocation of this method specifies a set of notifications. Therefore, objects may register as observers of different notification sets by calling these methods several times.

When an object (known as the notification sender) posts a notification, it sends an NSNotification object to the notification center. The notification center then notifies any observers for which the notification meets the criteria specified on registration by sending them the specified notification message, passing the notification as the sole argument.

A notification center maintains a notification dispatch table which specifies a notification set for a particular observer. A notification set is a subset of the notifications posted to the notification center. Each table entry contains three items:

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.
Lefteris
  • 14,550
  • 2
  • 56
  • 95
  • Hi Lefteris, I did what you said and it worked - although I'll be honest I have no idea why as I have never heard of NSNotificationCenter before! Could you be so kind as to explain in layman's terms what happens here? I feel like this is something I should know! When I wake up tomorrow (it's 1:40am here) I will read up on this too - thanks for the solution! – user1309044 Jun 04 '12 at 00:38
  • It's 3:40 am here so i'll answer tmorrow too.. Btw you should accept the answer if it is working! – Lefteris Jun 04 '12 at 00:43
  • Thank you - I look forward to your reply - and accepted now :) goodnight! – user1309044 Jun 04 '12 at 00:53
  • I have updated the question, added some documentation and fixed the toggleLabel function to accept the notification as well so you can read the dictionary. – Lefteris Jun 04 '12 at 08:31
  • thank you Lefteris - much appreciated - I am sure it's going to prove very useful for me now and down the line too! – user1309044 Jun 04 '12 at 10:57