UIMoviePlayerControllerWillExitFullscreenNotification not received - iphone

My app is portrait only but, I would like to allow the user to rotate to landscape when watching full screen videos through a UIWebview. I've done some research and found that I should add my class as an observer for these notifications:
UIMoviePlayerControllerDidEnterFullscreenNotification
UIMoviePlayerControllerWillExitFullscreenNotification
I add and remove the class as an observer like this:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerDidEnterFullScreen:) name:#"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerWillExitFullScreen:) name:#"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"UIMoviePlayerControllerWillExitFullscreenNotification" object:nil];
}
- (void)moviePlayerDidEnterFullScreen:(NSNotification *)notification
{
self.videoPlayingFullScreen = YES;
}
- (void)moviePlayerWillExitFullScreen:(NSNotification *)notification
{
self.videoPlayingFullScreen = NO;
}
- (NSUInteger)supportedInterfaceOrientations
{
if (self.videoPlayingFullScreen)
{
return UIInterfaceOrientationMaskAllButUpsideDown;
}
return UIInterfaceOrientationMaskPortrait;
}
My problem is: I never receive the "UIMoviePlayerControllerWillExitFullscreenNotification". I can't use the UIMoviePlayerControllerDidExitFullscreenNotification because if the user is finished watching the fullscreen video in landscape orientation and presses "done" the previous view controller also appears in landscape orientation when it should be in portrait.
Is there another way to detect when the user "did" enter fullscreen and "will" exit fullscreen? Or is there something that I am missing?
EDIT:
My app is for iOS 7 only.

The reason you're not getting the UIMoviePlayerControllerWillExitFullscreenNotification callback is because you're removing yourself as an observer on viewWillDisappear:

Since these callbacks are undocumented I used Javascript events (as H2CO3 suggested here) to determine when the video began, ended, or paused.
By the way I'm using the YouTube Player.
First, I setup the UIWebview and set my ViewController as the delegate.
Next, I loaded the HTML file into the UIWebview.
Index.html
<html>
<body bgcolor=#8C1717 style="margin:0px;">
<div id="ytplayer"></div>
<script type="text/javascript">
var tag = document.createElement('script');
tag.src = "https://www.youtube.com/player_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
var player;
function onYouTubeIframeAPIReady()
{
player = new YT.Player('ytplayer',
{
height: 'videoHeight',
width: 'videoWidth',
videoId: 'videoID',
playerVars: { 'showinfo':0, 'rel':0 },
events: { 'onStateChange': onPlayerStateChange }
});
}
function playerDidBeginPlaying()
{
document.location.href = "fake://video-began";
}
function playerDidEndPlaying()
{
document.location.href = "fake://video-ended";
}
var done = false;
function onPlayerStateChange(event)
{
if (event.data == YT.PlayerState.PLAYING && !done)
{
done = true;
playerDidBeginPlaying();
}
else if (event.data == YT.PlayerState.ENDED)
{
playerDidEndPlaying();
}
else if (event.data == YT.PlayerState.PAUSED)
{
playerDidEndPlaying();
}
}
</script>
</body>
</html>
Inside the ViewController
NSError *error = NULL;
NSString *path = [[NSBundle mainBundle] pathForResource:#"index" ofType:#"html"];
NSString *html = [[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:&error];
if (error)
{
#ifdef DEBUG
NSLog(#"[YouTube Webview] Error: %#", [error description]);
#endif
}
[self.webView loadHTMLString:html baseURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]]];
Then, I implemented the method webView:shouldStartLoadWithRequest:navigationType: to get notified when the events happened.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
if ([[[request URL] absoluteString] hasPrefix:#"fake://video-began"])
{
self.videoPlayingFullScreen = YES;
return NO;
}
else if ([[[request URL] absoluteString] hasPrefix:#"fake://video-ended"])
{
self.videoPlayingFullScreen = NO;
return NO;
}
return YES;
}

Related

UIWebView in full screen hides status bar

I am opening video in UIWebView with following code.
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
NSLog(#"Navigatin Type %d %#",navigationType, request);
if (navigationType == 0) {
self.navigationItem.leftBarButtonItem = backBarBtn;
[self showVideoInWebView:[request.URL absoluteString]];
return NO;
}
return YES;
}
-(void)showVideoInWebView:(NSString *)urlStr
{
[mainWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlStr]]];
}
but when my mainWebView opens in full screen it hides my status bar.
I don't want to hide status bar
then how can I show my status bar?
You Can set Notification For making Status bar Visible.
Set The Notification for FullScreen Entry And Exit Notification ,SO that you could SHow And Hide The Status bar As Needed.
// For FullSCreen Entry
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(videoFullScreen:) name:#"UIMoviePlayerControllerDidEnterFullscreenNotification" object:nil];
// For FullSCreen Exit
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(videoExitFullScreen:) name:#"UIMoviePlayerControllerDidExitFullscreenNotification" object:nil];
- (void)videoFullScreen:(id)sender
{
[[UIApplication sharedApplication] setStatusBarHidden:NO animated:NO];
}
- (void)videoExitFullScreen:(id)sender
{
//Here do WHat You want
}
I am Sure It'll be helpful to you.
that is the behaviour of the built-in movie player AFAIK you cant change it ... maybe with an alternative HTML5 control.
when your UIWebView begin Fullscreen at that time write this line..
just try with this line..
-(void)moviePlayerEvent:(NSNotification*)aNotification{
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:NO];
NSLog(#"%i", [UIApplication sharedApplication].statusBarHidden);
}
Another Way:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(VideoFullScreenExit:) name:UIWindowDidBecomeHiddenNotification object:self.view.window];
- (void)VideoFullScreenExit:(id)sender {
[[UIApplication sharedApplication] setStatusBarHidden:NO];
}

Viewing YouTube video inside app with return to previous ViewControlloer

I'm trying to integrate in my app a youtube video. But I want it to resume to the calling viewController when video finished. I've succeeded to almost implement that but in my way the user must press done button and then another to get back to the original ViewController.
This is the code I use, Please help, I prefer with ref to full code or code example.
YouTubeView.h :
#import <UIKit/UIKit.h>
#interface YouTubeView : UIWebView
{
}
- (YouTubeView *)initWithStringAsURL:(NSString *)urlString frame:(CGRect)frame mimeSubType:(NSString *)mimeType;
#end
YouTubeView.m :
#import "YouTubeView.h"
#interface YouTubeView ()
#end
#implementation YouTubeView
- (YouTubeView *)initWithStringAsURL:(NSString *)urlString frame:(CGRect)frame mimeSubType:(NSString *)mimeType
{
NSString *strMimeType;
if([mimeType length]>0)
{
strMimeType = mimeType;
}
else
{
strMimeType =#"x-shockwave-flash"; //#"x-shockwave-mp4";
}
if (self = [super init])
{
// Create webview with requested frame size
self = [[UIWebView alloc] initWithFrame:frame];
// HTML to embed YouTube video
NSString *videoHTML = [NSString stringWithFormat:#"\
<html>\
<head>\
<style type=\"text/css\">\
iframe {position:absolute; top:50%%; margin-top:-130px;}\
body {background-color:#000; margin:0;}\
</style>\
</head>\
<body>\
<iframe width=\"100%%\" height=\"240px\" src=\"%#\" frameborder=\"0\" allowfullscreen></iframe>\
</body>\
</html>", urlString];
[self loadHTMLString:videoHTML baseURL:nil];
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
#end
And a button that points to *on main ViewController :
-(IBAction)runTestVideo:(id)sender {
NSString *strNormalVdoURL = [NSString stringWithFormat:#"http://www.youtube.com/embed/TgLqH9n57B0"];
YouTubeView *videoVw = [[YouTubeView alloc] initWithStringAsURL:[NSString stringWithFormat:#"%#",strNormalVdoURL] frame:CGRectMake(0,0,315,420) mimeSubType:#"x-shockwave-flash"];
[self.view addSubview:videoVw];
[videoVw release];
videoVw = nil;
}
Please help.
I'm not quite sure if my method would work on yours as for mine, I had the view hidden when the video is playing. After the user pressed the done button, the movie controller will exit and the view is shown.
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector (MPMoviePlayerDidExitFullScreen;) name:MPMoviePlayerDidExitFullscreenNotification object:nil];
}
- (void)MPMoviePlayerDidExitFullScreen:(NSNotification *)notification {
[[NSNotificationCenter defaultCenter] removeObserver:self name: MPMoviePlayerDidExitFullscreenNotification object:nil];
[movieController stop];
[movieController.view removeFromSuperview];
view.hidden = NO;
}

iPhone headache - Threads, notifications, and URL Async connections

Some code instead of a long explanation.
The problem is :
When called from viewDidLoad, the server call triggers the delegates methods (connectionDidFinishLoading, etc...). But when called from XMLFileFullParsed, the request is launched to the server, but those same methods are not triggered.
If i call [self loadXMLDatas] instead of threading it, both server calls work fine.
Why ?
I start here :
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(foundaTag:) name:#"foundaTag" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(XMLFileFullParsed:) name:#"XMLFileFullParsed" object:nil];
self.server = [[ServerCommManager alloc] initWithServer:#"http://someserver/"];
[self.server sendQuestionWithCallIdentifier:#"IDENTIFIER" onPage:#"testpage.php" withParams:nil sendAnswerToObject:self]; // -- This one works
[NSThread detachNewThreadSelector:#selector(loadXMLDatas) toTarget:self withObject:nil];
}
- (void) loadXMLDatas {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
Do things, create a XMLparser, start to parse.
[pool release];
}
- (void) XMLFileFullParsed:(NSNotification*)notification {
[self.server sendQuestionWithCallIdentifier:#"IDENTIFIER" onPage:#"testpage.php" withParams:nil sendAnswerToObject:self]; // -- This one doesn't work
}
XMLParser.m
- (void) doYourJob {
[self doTheJob];
[[NSNotificationCenter defaultCenter] postNotificationName:#"XMLFileFullParsed" object:nil userInfo:nil];
}
- (void) doTheJob:(XMLTag*)tag {
if ([tag.name isEqualToString:#"searchedtag"]) {
theData = extract some datas
[[NSNotificationCenter defaultCenter] postNotificationName:#"foundaTag" object:self userInfo:[NSDictionary dictionaryWithObject:theData forKey:#"data"]];
return;
}
for (XMLTag* aTag in tag.childtags) {
[self doTheJob:aTag];
}
}
Deep inside the server comm.m
- (void) executeRequest {
some init
self.connection = [NSURLConnection connectionWithRequest:urlRequest delegate:self];
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response {
}
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data
{
}
- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error
{
}
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
}
From the code you've given, the notification is being posted from another Thread rather than the Main Thread where you've registered the observer.
In Apple's Notification Documentation, it says
In a multithreaded application, notifications are always delivered in the thread in which the notification was posted, which may not be the same thread in which an observer registered itself.
What you can do is move the notification into it's own method and then use performSelectorOnMainThread like so:
- (void) doTheJob:(XMLTag*)tag {
if ([tag.name isEqualToString:#"searchedtag"]) {
theData = extract some datas
[self performSelectorOnMainThread:#selector(sendNotification:) withObject:theData waitUntilDone:YES];
return;
}
for (XMLTag* aTag in tag.childtags) {
[self doTheJob:aTag];
}
}
- (void)sendNotification:(NSArray *)theData {
[[NSNotificationCenter defaultCenter] postNotificationName:#"foundaTag" object:self userInfo:[NSDictionary dictionaryWithObject:theData forKey:#"data"]];
}

MPMoviePlayerViewController and pinch out for full screen

i have search on the site but i haven't find the same problem as mine
when i do a pinch out on my video, the notification "MPMoviePlayerPlaybackDidFinishNotification" is called.
after, the "done" button put the video in pause and the player works badly...
I don't understand why this notification is called...
this is my code
- (id) init
{
self = [super init];
movie=[[MPMoviePlayerViewController alloc] init];
//we init the frame here and after the view rotate the video
[movie.view setFrame: CGRectMake(0, 0, 1024,768)];
return self;
}
+ (MoviePlayerManager*) getInstance
{
static MoviePlayerManager *movieSingleton;
if (movieSingleton==nil)
{
movieSingleton = [[MoviePlayerManager alloc]init];
}
return movieSingleton;
}
- (void) load:(NSURL*) a_videoFile withType:(VideoType)a_type
{
type = a_type;
[movie.moviePlayer setContentURL:a_videoFile];
switch (type) {
case VT_INTRO:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMovieFinishedCallbackIntro:) name:MPMoviePlayerPlaybackDidFinishNotification object:movie.moviePlayer];
break;
case VT_RESPONSE:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMovieFinishedCallbackResponse:) name:MPMoviePlayerPlaybackDidFinishNotification object:movie.moviePlayer];
break;
default:
NSLog(#"video Type not initialised");
break;
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMovieIsReadyToPlay:) name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification object:movie.moviePlayer];
[movie.moviePlayer prepareToPlay];
}
-(void)myMovieIsReadyToPlay:(NSNotification*)aNotification
{
[gsDelegate.view addSubview:movie.view];
[movie.moviePlayer play];
movie.moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
}
- (void) myMovieFinishedCallbackIntro:(NSNotification*)aNotification
{
NSNumber* reason = [[aNotification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
NSLog(#"%d",reason);
if(aNotification != nil)
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:movie.moviePlayer];
[gsDelegate movieIntroDidStop];
}
}
the NSNumber* reason = [[aNotification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
is the same for a pinch out or when i press "done"
thx for your help (and sorry for my bad english ;op)
NSNumber* reason = [[aNotification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
NSLog(#"%d",reason);
NSNumber is an Objective-C object, not a primitive C type. You are displaying the pointer to the object, not the value.
Correct with:
NSLog(#"%#", reason);
OR change reason to an Integer:
int reason = [[userInfo objectForKey:#"MPMoviePlayerPlaybackDidFinishReasonUserInfoKey"] intValue];
NSLog(#"%d", reason);

How can the subView detect that the mainView is rotating?

I have a mainView. To this view, I am adding a view of the same size. When the mainView(the background) rotates, its being detected but the subview doesnt have any idea about being rotated. And its functions are not even being called. Even when the program launches too, if I am in landscape mode, its the same way.
How can I make the subView know that the device is being rotated?
Perhaps you can shoot an event from the mainView to the subView, like so (in mainView):
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
[subView didRotateFromInterfaceOrientation:fromInterfaceOrientation];
}
I quickly grew frustrated by the lack of rotation notification support for non-primary UIViewController instances.
So I baked my own as a UIViewController extension. Note that this is purely for rotation detection within the subview, it won't rotate the subview - I'm working on that part now.
Source code then example usage below.
// Released under license GPLv3.
// Copyright (c) 2012 N David Brown. All Rights Reserved.
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
// Note: 'shouldAutorotateToInterfaceOrientation:' is automatically called by
// 'willRotate..', 'didRotate..' method calling notification handler
// blocks, so typically will not be desired for notification.
#define NOTIFY_SHOULD_AUTOROTATE 0
#interface UIViewController (NDBExtensions)
// For dispatchers.
#if NOTIFY_SHOULD_AUTOROTATE
-(void)notifyShouldAutorotate:(UIInterfaceOrientation)toInterfaceOrientation;
#endif
-(void)notifyWillRotate:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
-(void)notifyDidRotate:(UIInterfaceOrientation)fromInterfaceOrientation;
// For listeners.
#if NOTIFY_SHOULD_AUTOROTATE
-(void)listenForShouldAutorotate;
#endif
-(void)listenForWillRotate;
-(void)listenForDidRotate;
-(void)listenForAnyRotate;
-(void)stopListeningForAnyRotate;
#end
#implementation UIViewController (NDBExtensions)
#if NOTIFY_SHOULD_AUTOROTATE
-(void)notifyShouldAutorotate:(UIInterfaceOrientation)toInterfaceOrientation {
NSString *name = #"shouldAutorotate";
NSString *key = #"toInterfaceOrientation";
NSNumber *val = [NSNumber numberWithInt:toInterfaceOrientation];
NSDictionary *info = [NSDictionary dictionaryWithObject:val forKey:key];
[[NSNotificationCenter defaultCenter] postNotificationName:name object:nil userInfo:info];
}
#endif
-(void)notifyWillRotate:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
NSString *name = #"willRotate";
NSString *key = #"toInterfaceOrientation";
NSNumber *val = [NSNumber numberWithInt:toInterfaceOrientation];
NSString *key2 = #"duration";
NSNumber *val2 = [NSNumber numberWithDouble:duration];
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:val,key,val2,key2,nil];
[[NSNotificationCenter defaultCenter] postNotificationName:name object:nil userInfo:info];
}
-(void)notifyDidRotate:(UIInterfaceOrientation)fromInterfaceOrientation {
NSString *name = #"didRotate";
NSString *key = #"fromInterfaceOrientation";
NSNumber *val = [NSNumber numberWithInt:fromInterfaceOrientation];
NSDictionary *info = [NSDictionary dictionaryWithObject:val forKey:key];
[[NSNotificationCenter defaultCenter] postNotificationName:name object:nil userInfo:info];
}
#if NOTIFY_SHOULD_AUTOROTATE
-(void)listenForShouldAutorotate {
[[NSNotificationCenter defaultCenter]
addObserverForName:#"shouldAutorotate"
object:nil queue:nil
usingBlock:^(NSNotification* notification){
NSNumber *val = [[notification userInfo] objectForKey:#"toInterfaceOrientation"];
UIInterfaceOrientation toInterfaceOrientation = (UIInterfaceOrientation)[val intValue];
[self shouldAutorotateToInterfaceOrientation:toInterfaceOrientation];
}];
}
#endif
-(void)listenForWillRotate {
[[NSNotificationCenter defaultCenter]
addObserverForName:#"willRotate"
object:nil queue:nil
usingBlock:^(NSNotification* notification){
NSNumber *val = [[notification userInfo] objectForKey:#"toInterfaceOrientation"];
UIInterfaceOrientation toInterfaceOrientation = (UIInterfaceOrientation)[val intValue];
NSNumber *val2 = [[notification userInfo] objectForKey:#"duration"];
NSTimeInterval duration = [val2 doubleValue];
if ([self shouldAutorotateToInterfaceOrientation:toInterfaceOrientation]) {
[self willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
}];
}
-(void)listenForDidRotate {
[[NSNotificationCenter defaultCenter]
addObserverForName:#"didRotate"
object:nil queue:nil
usingBlock:^(NSNotification* notification){
NSNumber *val = [[notification userInfo] objectForKey:#"fromInterfaceOrientation"];
UIInterfaceOrientation fromInterfaceOrientation
= (UIInterfaceOrientation)[val intValue];
UIInterfaceOrientation toInterfaceOrientation
= (UIInterfaceOrientation)[[UIDevice currentDevice] orientation];
if ([self shouldAutorotateToInterfaceOrientation:toInterfaceOrientation]) {
[self didRotateFromInterfaceOrientation:fromInterfaceOrientation];
}
}];
}
-(void)listenForAnyRotate {
#if NOTIFY_SHOULD_AUTOROTATE
[self listenForShouldAutorotate];
#endif
[self listenForWillRotate];
[self listenForDidRotate];
}
-(void)stopListeningForAnyRotate {
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"shouldAutorotate" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"willRotate" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"didRotate" object:nil];
}
#end
Example usage:
// In PrimaryViewController.h (instance of this contains 'view'
// which is first subview in window).
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
// Normal rules go here.
return UIInterfaceOrientationIsPortrait(toInterfaceOrientation);
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
// Normal rules go here.
// ..and notification dispatch:
[self notifyWillRotate:toInterfaceOrientation duration:duration];
}
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
// Normal rules go here.
// ..and notification dispatch:
[self notifyDidRotate:fromInterfaceOrientation];
}
// In OtherViewController.h (this could be any non-primary view controller).
-(void)viewDidLoad {
[self listenForAnyRotate];
}
-(void)viewDidUnload {
[self stopListeningForAnyRotate];
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {
// Normal rules go here.
return UIInterfaceOrientationIsPortrait(toInterfaceOrientation);
}
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation
duration:(NSTimeInterval)duration {
// Normal rules go here.
NSLog(#"#willRotate received!");
}
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
// Normal rules go here.
NSLog(#"#didRotate received!");
}
You could fire an NSNotification when the main view is rotated, which the subview is registered to listen for. There's a quick overview of NSNotification over here.
One advantage of this approach is that objects other than subclasses of UIView can listen for this notification.