Best Method to Show a Popup Transparent Window on iPhone?

35,763

Solution 1

do you want to achieve this?

enter image description here

Here are two different viewControllers one above other one. vc2 is a childViewController of vc1 with a transparent background. In your case you can put a UILabel top of the stack with backgroundColor black and alpha = 0.5.

All events of vc2 will fire on vc2.m. Use this code on image click:

- (IBAction)imageClick 
{
    vc2 *viewController = [[vc2 alloc]init];
    [self addChildViewController:viewController];
    viewController.view.frame = self.view.frame;
    [self.view addSubview:viewController.view];
    viewController.view.alpha = 0;
    [viewController didMoveToParentViewController:self];

    [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^
     {
         viewController.view.alpha = 1;
     }
                     completion:nil];
}

And in vc2.m put this on viewDidLoad to make this viewControllertransparent.

self.view.backgroundColor = [UIColor clearColor];
self.view.opaque = YES;

Making transparent view a viewController will make your code clean as all code of vc2 will be in a separate class.

EDIT

So do one thing, First add a UIView to your xib which will be a rounded border and frame will be that you want as per your screenshot.

For rounded border, you can use this category. backgroundColor of this UIView will be clearColor:

- (void)setRoundedBorder:(float) radius borderWidth:(float)borderWidth color:(UIColor*)color
{
    CALayer * l = [self layer];
    [l setMasksToBounds:YES];
    [l setCornerRadius:radius];
    // You can even add a border
    [l setBorderWidth:borderWidth];
    [l setBorderColor:[color CGColor]];
}

Now put a UILabel/UIView/UIImage whose frame is equal to UIView above and alpha is 0.5 with black background color. You can do this directly from xib. No need to set frame through code.

Then start putting your other controls inside UIView

Solution 2

Try this

// create a new view
  UIView *viewPopup=[[UIView alloc]init];
  [viewPopup setBackgroundColor:[UIColor blackColor]];
  viewPopup.alpha=0.6f;

 // add into window
 AppDelegate *appdelgateobj=(AppDelegate *)[[UIApplication sharedApplication]delegate];
 [appdelgateobj.window addSubview:viewPopup];
 [appdelgateobj.window bringSubviewToFront:viewPopup];

Solution 3

Follow below step for transparent view :

step 1: enter image description here

step 2:

enter image description here

  • Whenever you want it Transpertview.hidden=NO:
  • whenever you don't want then Transpertview.hidden=YES:

may be it will help.

Solution 4

Add #import <QuartzCore/QuartzCore.h> framework in your .m file and use following code

UIWindow* window = [UIApplication sharedApplication].keyWindow;
    self.dimView = [[UIView alloc] initWithFrame:window.bounds];
    self.dimView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:.6];
    self.dimView.userInteractionEnabled = YES;
    [window addSubview:self.dimView];

This above is transparent dimView which size is similar to window.

self.searchTblContainerView = [[UIView alloc] init];
    self.searchTblContainerView.frame = CGRectMake(15, (window.frame.size.height - 300) / 2, 290, 300);
    self.searchTblContainerView.layer.cornerRadius = 15.f;
    self.searchTblContainerView.layer.borderColor = [UIColor blackColor].CGColor; /// set color as per your requirement
    self.searchTblContainerView.layer.borderWidth = 2.f;
    self.searchTblContainerView.alpha = 0.80; /// set as per your requirement 
    self.searchTblContainerView.clipsToBounds = YES;
    [self.dimView addSubview:self.searchTblContainerView];

above self.searchTblContainerView is main view that contain your whole UIControls such like label, textField, Button, etc... and set it as per your requirement.

Set by default hidden property of self.dimView.hidden = YES; and display and hide by following animation like alertView (apple).

Following code for display dimView.

self.searchTblContainerView.transform = CGAffineTransformMakeScale(0.01, 0.01);
        [UIView animateWithDuration:0.30 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
            self.searchTblContainerView.transform = CGAffineTransformIdentity;
            self.dimView.hidden = NO;
        } completion:^(BOOL finished){}];

        UIWindow* window = [UIApplication sharedApplication].keyWindow;
        [window bringSubviewToFront:self.dimView];

Following code for hide dimView.

 self.searchTblContainerView.transform = CGAffineTransformIdentity;
    [UIView animateWithDuration:0.30 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
        self.searchTblContainerView.transform = CGAffineTransformMakeScale(0.01, 0.01);
    } completion:^(BOOL finished){
        self.dimView.hidden = YES;
    }];

Above code is simple logic, might be useful in your case.

Share:
35,763
Erika Electra
Author by

Erika Electra

I am a female programmer. I like Cinderella and Disney.

Updated on July 26, 2020

Comments

  • Erika Electra
    Erika Electra almost 4 years

    I'm building an iOS 6 iPhone app in Xcode 4.6 and am wondering about the best way to achieve the following type of popup window:

    PopoverScreenshot

    Specifically, the iPhone screenshot on the right, where, if a user taps on a face or UIView in the main window, a partially transparent popover appears with more detailed information -- such as a portrait photo and textual data -- but the original view (a photo collection here) remains visible, and the timers/counters continue ticking down in that view.

    I thought this would be a possible solution iPhone Modal View Smaller that the screen but it doesn't work for me. Not shown above is a cancel button that I am also planning to put in the popover, so that the user can return to the view underneath. When the timer expires, the detailed view also disappears.

    Should I use presentModalViewController and the presenter/presented scheme, or use a parent-child-view relationship with a storyboard segue, or should I use loadNibNamed, or some kind of hack to overcome the iPhone's limitation of displaying a non-full-screen modal view? It'll cover most of the screen but I want to make sure the view underneath is visible and still active, since it provides information to the user that isn't in the popover (timer, etc.). The user won't need to interact with the screen below, but I'd like it to be partially visible.

    I designed the popup view as a separate viewcontroller in my main storyboard, not as a xib file. The connections and outlets are formed from interface builder to my code, called ProfileViewController.

    WARNING: My terminology may be incorrect and inaccurate. The popup or popover can be a UIView, UIViewController, UIWindow, or whatever works best programatically to solve the problem. I'm not tied to it being a certain widget type, as long as the functionality mirrors what I'm seeking.

    Thanks in advance for your suggestions!

  • Erika Electra
    Erika Electra over 10 years
    iPatel: Thank you for the logic and code. I take it then that I do not need a separate ViewController to handle the dimView? Just subclass UIView and do everything in code with regards to the stuff displayed in the dimView, and let the underlying PhotoCollectionViewController handle displaying, hiding, instantiating the dimView? (i.e. when you say .m file, you mean UnderlyingViewController.m, not DimWindowViewController.m, and there are no segues involved, only showing and hiding).
  • iPatel
    iPatel over 10 years
    if you dont want to use dimView then it is not important/require to use ,, i just use dimView for you custom view look like alertView.
  • Erika Electra
    Erika Electra over 10 years
    Kalpesh: Thanks, I like the simplicity of the solution. My concern is how can I place custom elements into the popup? (Well, I know how to add properties and member vars, but I meant like knowing where elements that I want to appear on the screen need to go to look right, etc. Any way to design the new view in Interface Builder? Like instead of text numbers, I have an animated barGraph. I know how to instantiate those in code, but not to place them in exactly the right location. Is this just trial and error?)
  • Erika Electra
    Erika Electra over 10 years
    No, I'm okay with the dimView, just not as confident in designing a UIView without visual guidance. I'm kind of spoiled by Interface Building, so I automatically assumed I needed a ViewController if I were designing the popup in IB and making all my outlets & connections there through ctrl-drag. Not sure how I can make it a UIView instead, without a ViewController.
  • Erika Electra
    Erika Electra over 10 years
    Yeah, your screenshot is basically what I want, except with mine being transparent and also giving the user an option to click buttons on it to return info back to the calling ViewController. Let me give this a try, I'll get back.
  • Erika Electra
    Erika Electra over 10 years
    Dhaval Bhadania: Just one question. If I drag in that UIImageView or UIView and perform all of my design & layout inside that, where does it go? Like, if I drag it on top of the calling ViewController in storyboard, it'll cover everything and prevent me from editing the original. If I leave it off to the side, it won't appear in the right place when it is loaded... or is there a way to programatically re-align it?
  • Dhaval Bhadania
    Dhaval Bhadania over 10 years
    if you want to add programmatically then go with @iPatel answer.
  • Erika Electra
    Erika Electra over 10 years
    This appeared on the line viewController.view.frame = self.view.frame;.........Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSPlaceholderMutableString initWithString:]: nil argument' *** First throw call stack: (0x160b012 0x1318e7e 0x160adeb 0xd49e68 0x1d569 0x1d06c 0x33e1c7 0x33e232 0x5724 0x61db 0x52785a 0x52699b 0x5280df 0x52ad2d 0x52acac 0x522a28 0x28f972 0x28fe53 0x26dd4a 0x25f698 0x266ddf9 0x266dad0 0x1580bf5 0x1580962 0x15b1bb6 0x15b0f44 0x15b0e1b 0x266c7e3 0x266c668 0x25cffc 0x221d 0x2145) libc++abi.dylib: terminate called throwing an exception
  • Erika Electra
    Erika Electra over 10 years
    No, ideally I'd like a hybrid of both, like layout my design in Interface Builder since there are a ton of little widgets that need to be carefully placed in the popup, but instantiate a version of the popup in code, if possible.
  • Vaibhav Saran
    Vaibhav Saran over 10 years
    As I said, put a semi transparent UILabel with label.frame = self.view.frame. And for cross button click use this code: [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^ { self.view.alpha = 0; } completion:^(BOOL finished) { if(finished) { [self.view removeFromSuperview]; } }];
  • Erika Electra
    Erika Electra over 10 years
    Sorry for asking another question, but why do we need the UILabel? Shouldn't we make the top View in the stack something like a UIView with a transparent background, or a UIImage with a transparent image loaded? (Just wondering, as it seems counterintuitive)
  • Erika Electra
    Erika Electra over 10 years
    I just tried putting a UILabel or a UIImageView at the top of the stack, and it deleted everything I already had in my stack! Copy/paste didn't work either, it just took one of my copied elements and replaced the top of the stack; everything else disappeared. How do I keep the stuff in the top View that I already have drawn and laid out (and attached)?
  • Vaibhav Saran
    Vaibhav Saran over 10 years
    yes you can use anything UIImage, UILabel, or UIView. Both 2 are more memory efficient than UIImage, thats it. Top of stack means UILabel/UIImage will look at top of that viewController's other views in xib or storyboard so that will go underneath all the views
  • Erika Electra
    Erika Electra over 10 years
    Where I set label.frame = self.view.frame? It seems like I can load the xib from Storyboard using instantiateViewControllerUsingIdentifier but as soon as I refer to anything to do with its frame, the app crashes! Here is the new error message
  • Erika Electra
    Erika Electra over 10 years
    reason: '*** -[NSPlaceholderMutableString initWithString:]: nil argument' *** First throw call stack:
  • Erika Electra
    Erika Electra over 10 years
    Thank you for your patience! Okay, for the most part, this worked. The only thing I still need to debug is the view not covering the places I think it would. In storyboard editor, it of course covers the entire screen, and I took out the battery bar, even. But when I load it, despite setting the frame to self.frame, the individual elements in the popup are shifted down so they are cut off at the bottom of the screen. The individual items are okay, it just doesn't start at the top like it should. Any way to align everything properly so they start at the top?
  • Vaibhav Saran
    Vaibhav Saran over 10 years
    could you send me a screenshot.
  • Erika Electra
    Erika Electra over 10 years
    I fixed the frame bounds, but I do have one question. If I am waiting for some kind of return value from the popup (like making a choice or entering a value) so the lower view can return, how can I do that? Right now, I am calling the view to come up and returning a value, but the value gets returned before the view is displayed, so it's a junk value. [UIView animateWithDuration:0.25 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^ { profViewController.view.alpha = 1; } completion:nil]; return profViewController.neededIndex; }
  • user3099609
    user3099609 over 9 years
    This solution will not show on top of the tab bar, as the initial mockup indicates. Also it will not work properly if you have a navigation bar (will not cover it). Same goes for modal views. Same goes for cases when there are multiple child VCs on the same screen.
  • Kalpesh
    Kalpesh about 9 years
    @Korben use this [viewPopup removeFromSuperview]; viewPopup=nil;