简体   繁体   中英

Pop up UIViewController with an IBAction UIViewController

Is it possible to pop up an UIViewController (xib file) like UIPopOverControl in iPad ?

I have a separate NIB file which is linked to an UIViewController . I want to popup that NIB file along with the button pressed with a customised size (200,200).

Is this possible?

I am trying to get something like this on the iPhone - http://www.freeimagehosting.net/c219p

You can also use one of these custom made clases to show a popup:

https://github.com/sonsongithub/PopupView

https://github.com/werner77/WEPopover

https://github.com/50pixels/FPPopover

Example with FPPopover:

//the view controller you want to present as popover
YourViewController *controller = [[YourViewController alloc] init]; 

//our popover
FPPopoverController *popover = [[FPPopoverController alloc] initWithViewController:controller]; 

//the popover will be presented from the okButton view 
[popover presentPopoverFromView:okButton]; 

//release if you arent using ARC
[controller release];

yes it is. load Your pOpOver controller lazily at the point when it is needed. add its view as a subview (you could animate the addition). make its frame size what You need and add the image You have shown as a background subview of the pOpOver controller along with other controls You want in the pop up.

good luck

UPDATE:

alright, ii will show You how ii do this in my app Lucid Reality Check (deployment target iOS4.3).

one can use a UIPopoverController to present another controllers view. what ii do first is to make sure ii always know the current orientation of the device, so ii can reposition the popup on rotation (maybe this works by itself on iOS6?). so in my base controller (from where ii want to show a popup) ii have an instance variable like this:

  UIInterfaceOrientation toOrientation;

and also:

  UIPopoverController *popover;
  UIButton            *popover_from_button;
  BOOL                 representPopover;

popover will be reused for all popups, and popover_from_button will hold the button from which the popup is initiated.

then the next code comes into the base controller:

- (void)popoverWillRotate {
  if ([popover isPopoverVisible]) {
      [self dismissPopover];
      representPopover = YES;
  }
}

- (void)popoverDidRotate {
  if (popover && representPopover) {
      representPopover = NO;
      [self representPopover];
  }
}

these two methods have to be called every time the device is rotated, like this:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
  //DLOG(@"willRotateTo %i", toInterfaceOrientation);
  toOrientation = toInterfaceOrientation;
      if ([Kriya isPad ]) {
          [self popoverWillRotate];
      }
}

as one can see, first the orientation is captured then popoverWillRotate is called. this would hide the popover during the orientation animation. and after rotating, the popover must be redisplayed like this:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
        //DLOG(@"didRotateFrom %i", fromInterfaceOrientation);
    //[self layout:toOrientation]; //do some layout if You need 
    if ([Kriya isPad]) {
        [self popoverDidRotate];
    }
}

- (void)layout:(UIInterfaceOrientation)toInterfaceOrientation {
    //one can do view layout here, and call other controllers to do their layout too
}

now that the orientation changes are worked out, the code for presenting the popover arrives here:

#pragma mark Popovers
- (void)presentPopoverWith:(id)controller fromButton:(UIButton*)button {
    if (popover)
       [popover release];
    if (popover_from_button)
        [popover_from_button release];
    popover_from_button = [button retain];
    popover = [[UIPopoverController alloc] initWithContentViewController:controller];
    [popover setDelegate:self];
    [self representPopover];
}

- (void)representPopover{
    if (popover) {
        UIPopoverArrowDirection arrowDirection = UIPopoverArrowDirectionAny;
        UIViewController *vc = (UIViewController*)[popover contentViewController];
        CGSize contentSize = [vc contentSizeForViewInPopover];

        if (contentSize.width > 0 && contentSize.height > 0) {
            [popover setPopoverContentSize:contentSize animated:NO];
        }
        //DLOG(@"representPopover rect:%@", [Kriya printRect:popover_from_button.frame]);
        [popover presentPopoverFromRect:CGRectOffset(popover_from_button.frame, 0, popover_from_button.frame.size.height + 7.0)  inView:self.view permittedArrowDirections:arrowDirection animated:YES];   
    }
}

- (void)dismissPopover {
    if (popover) {
        [popover dismissPopoverAnimated:YES];
   }
}

finally, if one wants to be notified when the popover is dismissed, the base controller must implement a delegate method:

#pragma mark UIPopoverControllerDelegate
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController {
    //do something important here like drink some water
}

and don't forget to make the base controller a UIPopoverControllerDelegate in its header.

a use case for this way of doing popups would then look like this:

- (void)takeImage {    
    UIImagePickerController *picker = [[[UIImagePickerController alloc] init] autorelease];
    [picker setDelegate:self];
    [picker setAllowsEditing:NO];
    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        [picker setSourceType:UIImagePickerControllerSourceTypeCamera];         
        if ([Kriya isPad]) {            
            [self presentPopoverWith:picker fromButton:backgroundImageButton];
        } else {
            //modals on iPhone/iPod
            //DLOG(@"takeImage addSubview picker");
            [self presentModalViewController:picker animated:YES];
        }
    } else {
        //DLOG(@"no camera");
    }
}

this would use an image picker as the content for the popup, but one can use any controller with a valid view. so just do this:

[self presentPopoverWith:popupsContentController fromButton:tappedButton];

one should not have any missing information, :), the method [Kriya isPad] is just this:

+ (BOOL)isPad {
  #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 30200
    // iPad capable OS
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
            //this is an iPad
            return YES;
        }else {
            //this is an iPod/iPhone
            return NO;
        }
  #else
      //can not pissible be iPad
          return NO;
  #endif
  }

ENJOY!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM