Few days ago I remembered Ray mentioned almost a year ago he liked the content popup window in the just released (back then) Pimpy application, and he thought it’d be a cool tutorial for Touch Code Magazine if I wrote how to implement it. I forgot for a long time about this conversation, but it came again to me last week.
So in this article I’m going to talk about:
- why use a Popup Window (Modal window) over using another UIViewController
- the mechanics I use to make a visually appealing popup window
- give you a download of a standalone Objective-C class you can use in your projects
Why use a Popup Window?
Going from one UIViewController to another, for example when you use a navigation controller pattern in your app, tells the user he’s going to another screen, to another task – he expects to do and see something new. If you use a popup window on the other hand to present some content it looks to the user only like a little detour, but still remaining in the general area where he or she is at that moment.
I often use a popup window to show:
- terms & conditions, manuals or any “additional information” to the screen the user is currently seeing
- show content from Internet
Another benefit is that your controller’s view won’t be released if you hit a Memory Warning; opposed to presenting another controller, when if you have a warning the not-visible controllers’ views will be released (that’s in case there’s something you need to hold on in your views)
The mechanics behind showing the popup window
Since there’s no UIKit class for showing a popup window, you can just have a UIView which looks like a little window. To make this window modal you’d also want to have a transparent or semi- transparent view covering the screen behind your popup window (so the user can’t interact with the UI behind the popup).
Now- just showing a view on the screen isn’t that nice is it? So a transition is really nice to have: I use flip from right/left to show my popups and it looks really nice.
Let’s have a look at part of my code (also included in the download project below):
bgView = [[[UIView alloc] initWithFrame: sview.bounds] autorelease]; [sview addSubview: bgView]; //faux view UIView* fauxView = [[[UIView alloc] initWithFrame: CGRectMake(10, 10, 200, 200)] autorelease]; [bgView addSubview: fauxView]; //the new panel bigPanelView = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, bgView.frame.size.width, bgView.frame.size.height)] autorelease]; bigPanelView.center = CGPointMake( bgView.frame.size.width/2, bgView.frame.size.height/2); [ … Here add the window contents inside bigPanelView …] //animation options UIViewAnimationOptions options = UIViewAnimationOptionTransitionFlipFromRight | UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState; //run the animation [UIView transitionFromView:fauxView toView:bigPanelView duration:0.5 options:options completion: ^(BOOL finished) { [ … some completion event handler … ] }]; |
Look at how I first add a bgView, which takes up the whole screen (actually the bounds of the superview sview); then I add a view called fauxView – this one has absolutely no visual role, it just has to be in the view hierarchy, so the actual content (inside bigPanelView) can flip around from this empty view. This way it looks like the popup window flips around out of the nothing – very cool trick
I actually haven’t seen this in another application
There’s one thing to mention about [UIView transitionFromView: toView: …… ]. This method basically flips around one view to another. What you need to know though is that it automatically adds the second view (the “to view”) to the view hierarchy, and at the same time removes the first view (the “from view”) from the view hierarchy.
So, in the code above both first and second views are autoreleased – thus when the transitions finishes the fauxView is removed and deallocated automatically, and the bigPanelView is retained by its superview.
So let’s see how things work:
- add a background container
- add an empty view inside
- create the content view (the popup window), but don’t add to the view hierarchy
- flip around the empty view into the content view
Let’s see all this in action!
MTPopupWindow – a standalone class to present popup windows
MTPopupWindow is a very simple free to use class, which gives you the ability to show HTML content with just one line of code. It implements the flip in and flip out transitions I just spoke about and here it is how it looks like:
To use the class download the XCode project below and inside you’ll find a folder called MTPopupWindow – copy this folder inside your project
Include the class:
#import "MTPopupWindow.h" |
To open a popup window showing an HTML file from your app’s bundle:
[MTPopupWindow showWindowWithHTMLFile:@"testContent.html" insideView:self.view]; |
(self is a UIViewController instance, since presumably this is called in an IBAction inside a view controller)
To open a popup window showing a web page:
[MTPopupWindow showWindowWithHTMLFile:@"http://www.underplot.com" insideView:self.view]; |
Where to go from here?
If you need to just show some HTML content – just copy over the MTPopupWindow group and use as described above. If you need to do something fancier inside your popup window – you’re welcome to read trough the very short class code and extend it as you wish.
MTPopupWindow demo project download.
I use this technique of presenting modal content for more than a year now – both in Doodle Booth and Pimpy and it really saves me bulk creating controllers, when I don’t really need them. Hope this was useful to you and if so please do leave me a comment and share it with your friends and colleagues.
Marin
·






Awesome post dude, would you be interested me allowing me to re-publish this post on my ios development blog: http://ios-blog.co.uk? This would benefit the community greatly.
I would of course give you an author profile and link back fully to the original? Please let me know
I hope that together we can benefit the community
Hi, you can certainly post about my article and/or link to it, but please do not re-post the full text. Thanks Marin
Thank you !!!!!!!
Exactly what I was looking for !!!!
I’ve added
// Interface rotation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait ||
interfaceOrientation == UIInterfaceOrientationLandscapeRight ||
interfaceOrientation == UIInterfaceOrientationLandscapeLeft
);
}
to this but it does not work correctly. How to fix it?
hi Mario, for the moment it supports only the portrait orientation, you can dig in the code any time you want
hi Martin, I’m digging in without success for now. My latest accomplishment is to crash app when user open popup in landscape mode.
I was going to add event to close popup on screen rotation but I cannot use closepopupwindow in my controller and I don’t know how to do it. :/
Maybe autoresizingMask will be good idea… and popup will be displayed properly in landscape… hmm…
Nice , useful demo project, looking forward to playing around with it. thanks for sharing!
Really nice, way for displaying popup view, thanks for sharing.
[...] the coolest code from Touch Code Magazine today to do an html file pop-over view on an iOS device. It looks like [...]
This help me a lot. thanks for sharing.
Thank you very much! Exactly what I was looking for.
I wanted to know if you could somehow tweak the opacity of the popup some? I’d like to be able to “see” through it some.
Thanks again!
Ooops…also forgot to mention.
is there a way to make the popup window shorter? I have a tab bar application and the tab bar on the bottom is covering up the bottom part of the window.
Thanks
No – unfortunately it’s only 1 size – but already few guys asked for it, so I might be making it more flexible and releasing an update. Don’t have it planned yet though
man, that would be so helpful.
thanks for responding.
Thank for sharing.
If I use your code in storyboard (ARC mode)
when click close button. It will show exc bad access error.
i check the info malloc-history. but cannot see any useful information.
Awesome solution! This is a really good way of “making detours”. Is it ok for me to use and modify your code in my app?
Hey Joakim, it’s totally ok – download, use and modify as you like. Marin
Awesome way of displaying info! Is it ok if I use this code in my app?
Thank you, this will really help out!
Nice Code !!
really have awesome look.
Thanks!!
[...] http://www.touch-code-magazine.com/showing-a-popup-window-in-ios-class-for-download/ [...]
[...] http://www.touch-code-magazine.com/showing-a-popup-window-in-ios-class-for-download/ カテゴリー: iPhoneアプリ開発 パーマリンク ← iTunesでのダウンロード数がチェック出来るアプリ [...]
Thank you very much! This is exactly what I’ve been trying to do in my app.
It is really helpful.
If it is okay to ask, do you know how to pass a value coming from another button to show in the pop up window??:)
Hi, usually to communicate with the contents of the uiwebview you will use “stringByEvaluatingJavaScriptFromString” – so you pass javascript code (as a string) and it will be executed inside the web page you are showing currently. Marin
Thanks

last question pls
For example I have a example.text = [example.text stringByAppendingFormat:@"%@", [allwords objectAtIndex:x]];
how can I show the example.text in my popup window? any idea?
–sorry for having too many questions.
Hi Marin,
When I try to use this in an Arc project I’m getting a EXC_BAD_ACCESS on the selector for the close button. Do you know how to get around this?
Thanks
Hi Marin,
When I port this into an Arc project I’m getting a bad access on the selector for the close button. How can I get around this?
Thanks
Hi Marin,
Awesome Class!! I want to use it as part of my project but am having difficulty using it with ARC. Keeps crashing when I click on the close button. Any thoughts?
Kenn
@Kenn
You can click on the project’s Target and select “Build Phases”. Under Compile sources double click on the popupWindowView.m file and type the following “-fno-objc-arc”. This will tell the compiler to neglect ARC and allow you to manually control your retain and release for that specific file. Good luck!
Hi,
This really is an excellent Post….I tried it and its working perfect….
I tried to change the code as per my requirement….
I want to load a screen (TestViewController) instead of the html file….When i added TestViewController instead of testContent.html…i am getting an empty screen. if i check the output window its showing error msg: PopupWindowProject[4014:f803] error loading TestViewController: The operation couldn’t be completed. (Cocoa error 260.)
Any help is highly appreciated
Thanks in advance
Thanx!
Wonderfull!
Hi,
thanks for this awesome piece of code.
But how do I resize the popup when i’m using Navigation and Tabbar Panel?
Regards
This popup window don’t resize, it’s works only in portrait full-screen mode, but it gives you a great example how to implement one for your own case. cheers, Marin
[...] MTPopupWindow [...]
Here’s a method for fixing the orientation
- (void) rotatePopup {
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (orientation != UIInterfaceOrientationPortrait) {
CGAffineTransform rotationTransform = CGAffineTransformIdentity;
if(orientation == UIInterfaceOrientationPortraitUpsideDown) {
rotationTransform = CGAffineTransformRotate(rotationTransform, [self degreesToRadians:-180]);
}
else if(orientation == UIInterfaceOrientationLandscapeLeft) {
rotationTransform = CGAffineTransformRotate(rotationTransform, [self degreesToRadians:-90]);
}
else if(orientation == UIInterfaceOrientationLandscapeRight){
rotationTransform = CGAffineTransformRotate(rotationTransform, [self degreesToRadians:90]);
}
bgView.transform = rotationTransform;
}
}
-(CGFloat) degreesToRadians:(CGFloat) degrees {
return degrees * M_PI / 180;
}
you can put it below
bigPanelView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, bgView.frame.size.width, bgView.frame.size.height)];
bigPanelView.center = CGPointMake( bgView.frame.size.width/2, bgView.frame.size.height/2 );
[self rotatePopup]; // rotate popup
Hope it helps
Thanks for posting this!
Actually the article about version 2 of the popup window is coming up in Friday, and the new version handles interface orientation by using Auto Layout, you can already have a preview of the code here if you want https://github.com/icanzilb/MTPopupWindow
[...] of the most popular articles on Touch Code Magazine is the one demoing my MTPopupWindow class. It was a class I put quickly together to showcase how you can create a cool animation and kind of [...]
Hello!Very nice approach,but i/ve problem to modificate your code for ios5.Can you help me with that?I’ve tried this
in my viewcontroller.m
- (IBAction)buttonLitersSelected:(id)sender {
PopupWindow* winPop = [[PopupWindow alloc] init];
[winPop showView:self.view];
}
And for popupwindow,i’ve written this
-(void)showView:(UIView*)v
{
//setup background
[self setupBackground:v];
//create the ok button
int okButtonOffset = 10;
UIImage* okButtonImg = [UIImage imageNamed:@"small_button_001.png"];
UIButton* okButton = [UIButton buttonWithType:UIButtonTypeCustom];
// [okButton setImage:okButtonImg forState:UIControlStateNormal];
[okButton setBackgroundImage:okButtonImg forState:UIControlStateNormal];
[okButton setFrame:CGRectMake(_background.frame.origin.x + okButtonOffset,
_background.frame.origin.y + _background.frame.size.height / 2 + okButtonOffset ,
okButtonImg.size.width + okButtonOffset,
okButtonImg.size.height + okButtonOffset)];
okButton.titleLabel.font = [UIFont fontWithName:@"AeroneticFuturistCyr" size:35];
[okButton setTitleColor:[UIColor colorWithRed:(31/255.0f) green:(165/255.0f) blue:(220/255.0f) alpha:1]
forState:UIControlStateNormal];
[okButton setTitle:@"Ok" forState:UIControlStateNormal];
[okButton addTarget:self action:@selector(closePopupWindow:) forControlEvents:UIControlEventTouchUpInside];
[v addSubview:okButton];
}
-(void)setupBackground:(UIView*)v
{
//popup container
_bgView = [[UIView alloc] initWithFrame:v.bounds];
_bgView.backgroundColor = [[UIColor alloc] initWithWhite:0.3 alpha:0.3];
[v addSubview:_bgView];
//image background
_background =[[UIImageView alloc]initWithImage:[UIImage imageNamed:@"back_win.png"]];
_background.center = CGPointMake(_bgView.frame.size.width/2, _bgView.frame.size.height/2);
[v addSubview:_background];
}
-(void)closePopupWindow:(id)sender
{
}
The popup window appears as expected,but when i click on okButton i receive a
EXC_BAD_ACCESS error.
I’ve cleaned the closePopupWindow method in order to find the error,but still not issues…
[...] of the most popular articles on Touch Code Magazine is the one demoing my MTPopupWindow class. It was a class I put quickly together to showcase how you can create a cool animation and kind of [...]