8

I need to send the notification @"willAnimateRotationToInterfaceOrientation" with the parameters toInterfaceOrientation and duration (question #1) to all UIViewController on the application (question #2). How to write code for that?

[[NSNotificationCenter defaultCenter]
  addObserver:self
     selector:@selector(willAnimateRotationToInterfaceOrientation:toInterfaceOrientation:duration)
         name:@"willAnimateRotationToInterfaceOrientation"
       object:nil];

[[NSNotificationCenter defaultCenter] 
  postNotificationName:@"willAnimateRotationToInterfaceOrientation"
                object:self];
Dmitry
  • 14,306
  • 23
  • 105
  • 189
  • Related question: http://stackoverflow.com/questions/15957077/event-willanimaterotationtointerfaceorientation-isnt-calling – Dmitry Apr 11 '13 at 20:04

3 Answers3

20

Use postNotificationName:object:userInfo: and bundle any parameter you wish to pass inside the userInfo dictionary.

Example:

You can post a notification like this

NSDictionary * userInfo = @{ @"toOrientation" : @(toOrientation) };
[[NSNotificationCenter defaultCenter] postNotificationName:@"willAnimateRotationToInterfaceOrientation" object:nil userInfo:userInfo];

And then retrieve the information you passed, by doing:

- (void)willAnimateRotationToInterfaceOrientation:(NSNotification *)n {
    UIInterfaceOrientation toOrientation = (UIInterfaceOrientation)[n.userInfo[@"toOrientation"] intValue];
  //..
}

To summarize what seen above, the selector used to handle a notification takes one optional parameter of type NSNotification and you can store any information you'd like to pass around inside the userInfo dictionary.

Gabriele Petronella
  • 106,943
  • 21
  • 217
  • 235
  • Code has the following errors: 1. Unexpected '@' in program. 2. Collection element of type 'UIInterfaceOrientation' (aka 'enum UIInterfaceOrientation') is not an Objective-C object. – Dmitry Apr 11 '13 at 20:26
  • 1
    You need to wrap `toOrientation` between parenthesis. Fixed. – Gabriele Petronella Apr 11 '13 at 20:45
1

This doesn't work the way you think it does. A notification message call has one optional parameter, which is an NSNotification object:

-(void)myNotificationSelector:(NSNotification*)note;
-(void)myNotificationSelector;

The notification object has a property, userInfo, which is a dictionary that can be used to pass relevant information. But you can't register arbitrary selectors to be called by the notification center. You pass that dictionary with the notification by using -postNotificationName:object:userInfo: instead of -postNotificationName:object:; the userInfo parameter is just an NSDictionary that you create.

Seamus Campbell
  • 17,816
  • 3
  • 52
  • 60
  • Thanks, but is it possible to send a notification to all (or all visible) `UIViewController`s of the application? – Dmitry Apr 11 '13 at 20:07
  • Only if they've all registered for that notification. Note that there is an existing notification, `UIDeviceOrientationDidChangeNotification` that is available if you ask for it by calling `[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications]` (but you still must register each view controller for it). – Seamus Campbell Apr 11 '13 at 20:10
  • `UIDeviceOrientationDidChangeNotification` is calling after a rotation - not inside the rotation as `willAnimateRotationToInterfaceOrientation`. Sorry for possible noob question, but we are calling `postNotificationName` with `object:self` parameter - will it be sent only to `self` object? – Dmitry Apr 11 '13 at 20:12
  • 1
    It will be sent to all objects that passed that pointer to the `object` parameter when they called `NSNotificationCenter -addObserver:selector:name:object:`. – Seamus Campbell Apr 11 '13 at 20:26
  • May I use `object:nil` on `addObserver:selector:name:object:` and on `postNotificationName:object:` both to send the notification to all subscribers? – Dmitry Apr 11 '13 at 20:29
  • 1
    Absolutely. In fact, you only have to pass `nil` in `addObserver:::`; you'll then get all the notifications, even if `postNotificationName:object:` has a non-`nil` value for `object`. – Seamus Campbell Apr 11 '13 at 20:37
  • Thank you a lot! May you also help to pass `UIInterfaceOrientation toInterfaceOrientation` and `NSTimeInterval duration` parameters with the notification? – Dmitry Apr 11 '13 at 20:41
  • 2
    See Gabriele's code. You need to push both values into `NSNumber`s, because `NSDictionary` can only hold object values. – Seamus Campbell Apr 11 '13 at 20:46
0

You make an easier to call method, which takes less arguments and does the complex call for you.

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

- (void)doStuff {
  [self willAnimateRotationToInterfaceOrientation:someOrientation
                                    toOrientation:someOtherOrientation
                                         duration:1];
}

You shouldn't be calling willAnimateRotationToInterfaceOrientation: yourself though. Instead make a method that's called form that method that contains the code you want to activate on rotation and also other times.

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337