Help with a little extra on the Silver Challenge


#1

I decided to go a little further on the Silver challenge and make it so when you shake the phone, it calls the randomColor method and changes the circle colors to a random color. However i also want it to reset the UISegmentedControl.

So in HypnosisViewController.m i created the following method:

-(void) resetColorPicker { colorPicker.selectedSegmentIndex = -1; NSLog(@"%i", [colorPicker selectedSegmentIndex]); }

and in HypnosisView.m i did the following for the motionBegan method:

-(void) motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event { if (motion == UIEventSubtypeMotionShake) { NSLog(@"Device started shaking!"); //[self setCircleColor: [UIColor grayColor]]; [self setCircleColor:[self randomColor]]; HypnosisViewController *hypVc = [[HypnosisViewController alloc] init]; [hypVc resetColorPicker]; } }

But when i put a debug point on the resetColorPicker method it never resets the colorPIcker… I’m pretty sure it’s because i;m not calling it correctly in the motionBegan method.

Any ideas on what i;m doing wrong and how to fix that?

Thanks!
Chris


#2

You are calling the method correctly. But you need to send the message to the HypnosisViewController that is already there and on the screen and not to a new one.

Greetings
Joerg


#3

This is where i’m a little confused… How do i call the existing HVC?


#4

Ignore this post, because it is wrong. See the following one.

In motionBegan:withEvent:, self points to the instance of the HypnosisViewController; you should invoke the method on that instance not on a new one:

-(void) motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    if (motion == UIEventSubtypeMotionShake) {
        NSLog(@"Device started shaking!");
        [self setCircleColor:[self randomColor]];
        [self resetColorPicker];
    }
}

#5

I tried using self and i get an error. The HypnosisViewController is in another file… The motionBegan event is defined in HypnosisView. Unless i;m missing a conncetion in order to make self work…


#6

Sorry, I should have read your post more carefully.

Try the following method.

The view does not know about its view controller. Despite this, in the view you need to cause the view controller’s resetColorPicker method to be invoked; you can do this easily by having the view send out a DeviceShake notification. The controller can pick up the notification and act on it.

The View sends out DeviceShake notifications:

-(void) motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
     ...
     [[NSNotificationCenter defaultCenter] postNotificationName:@"MyNotificationDeviceShake" object:self];
     ...
}

The View Controller receives the DeviceShake notifications:

- (void)viewDidLoad
{
    // We are interested in "DeviceShake" notifications
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (deviceShakeNotification:)     name:@"MyNotificationDeviceShake" object:nil];    
}

- (void)deviceShakeNotification:(NSNotification *)note
{
      // Reset the color picker
      if ([NSThread currentThread] == [NSThread mainThread])
      {
           //Do it directly
           [self resetColorPicker:nil];
      }
      else
      {
             // Arrange it to be done on the main thread
             [self performSelectorOnMainThread:@selector (resetColorPicker:nil:) withObject:nil waitUntilDone:NO];
      }
}

- (void)resetColorPicker:(NSObject)object
{
    // Reset the color picker
    ...
}

Make sure that you use the same notification name (MyNotificationDeviceShake) in both.


#7

That worked perfectly! Thanks so much! Good follow up after the Notifications section i just read…


#8

Sorry that I wasn’t able to answer - had some exams to write.
Well what you do is:

[quote]HypnosisViewController *hypVc = [[HypnosisViewController alloc] init]; [hypVc resetColorPicker];[/quote]
But you should have called resetColorPicker: ob the View Controller that is already on screen. You send it messages by having a HVC-property in your HV-class. Then when you init the HV-object, you could set the property to the current HVC.
That should have solved your problem. But anyway.

Greetings Joerg