I'm writing an app that needs to spawn a popover in order to add a new note. To that end, I have something that does kind of the trick, however, I can't seem to adjust the size of the popover. This is how I'm spawning it:
UIButton* btn =sender;
UIViewController* fooTroller = [[UIViewController alloc] init];
CGRect rectFoo = CGRectMake(0, 0, 100, 100);
UIView* fooView = [[UIView alloc] initWithFrame:rectFoo];
[fooView setBackgroundColor:[UIColor redColor]];
[fooTroller setView:fooView];
popOver =[[UIPopoverController alloc] initWithContentViewController:fooTroller];
[popOver presentPopoverFromRect:btn.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionLeft
animated:YES];
Any thoughts? It's not respecting the view size.
You should not be calling setView: on the view controller. Let the view controller setup its own view.
The proper way to size a popover is to either override the contentSizeForViewInPopover method of your view controller to return the size or to set the popoverContentSize property on the popover.
UIButton* btn =sender;
UIViewController* fooTroller = [[UIViewController alloc] init];
popOver = [[UIPopoverController alloc] initWithContentViewController:fooTroller];
popOver.popoverContentSize = CGSizeMake(100, 100);
[popOver presentPopoverFromRect:btn.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionLeft
animated:YES];
Related
I created a UpcomingCell.h and .m for the cell. In the button's tap method i tried this
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
// cameraSystemMenu = [mainStoryboard instantiateViewControllerWithIdentifier:#"CameraSystemMenuViewController"];
UIView *anchor = sender;
UIViewController *viewControllerForPopover =
[storyboard instantiateViewControllerWithIdentifier:#"yourIdentifier"];
self.popover = [[UIPopoverController alloc]
initWithContentViewController:viewControllerForPopover];
[self.popover presentPopoverFromRect:anchor.frame
inView:anchor.superview
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
and I also tried this
self.popoverContent = [[PopOverViewController alloc]init];
UIView *popoverView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 300)];
[popoverView setBackgroundColor:[UIColor purpleColor]];
self.popoverContent.view = popoverView;
self.popoverContent.contentSizeForViewInPopover = CGSizeMake(200, 300);
UIPopoverController *contactPopover =[[UIPopoverController alloc] initWithContentViewController:self.popoverContent];
[contactPopover presentPopoverFromRect:self.remindButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES ];
[contactPopover setDelegate:self];
and countless other popover examples on stackoverflow and I cant get it to work.
Both examples crashes. The first one crashes on
the rect passed in to this method must have non-zero width and height. This will be an exception in a future release
The second one crashes because an UIPopoverController needs to be a property or an instance variable, otherwise it will be deallocated on the end of the method, because the View that's showing it will not retain it
I have an iPad app (XCode 4.6, ios 6.2, ARC and Storyboards). I have drawn a GCRect on a position of a UIView.
CGRect rectangle = CGRectMake( [appSelected.aPosX floatValue], [appSelected.aPosY floatValue],[appSelected.aPosW floatValue], [appSelected.aPosH floatValue]);
I have a method that does the drawing for me; this is the code for that method:
-(void)showHTMLHelp:(NSString *)htmlString pointTo:(id)target background:(UIColor *)bgColor {
UIViewController* popoverContent = [[UIViewController alloc] init];
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 300)];
popoverView.backgroundColor = [UIColor colorWithWhite:(CGFloat)1.0 alpha:(CGFloat)1.0]; // frame color?
popoverContent.view = popoverView;
//resize the popover view shown in the current view to the view's size
popoverContent.contentSizeForViewInPopover = CGSizeMake(200, 300);
// add the UIWebView for RichText
UIWebView *webView = [[UIWebView alloc] initWithFrame:popoverView.frame];
webView.backgroundColor = [UIColor whiteColor]; // change background color here
// add the webView to the popover
[webView loadHTMLString:htmlString baseURL:[NSURL URLWithString:nil]];
[popoverView addSubview:webView];
//create a popover controller
popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
//present the popover view non-modal with a refrence to the button pressed within the current view
if([target isKindOfClass: [UITextField class]])
[popoverController presentPopoverFromRect:((UITextField *)target).frame inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
else if([target isKindOfClass: [UISegmentedControl class]])
[popoverController presentPopoverFromRect:((UISegmentedControl *)target).frame inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
else if([target isKindOfClass: [UIButton class]])
[popoverController presentPopoverFromRect:((UIButton *)target).frame inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
else
[popoverController presentPopoverFromRect:*(CGRect *)CFBridgingRetain(target)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
}
Now I want to have a UIPopover point to that rectangle. Since GCRect is a C structure, I can't figure out how to do it. This is what I tried, but obviously it's wrong. How can I do this? This is the code where I call the method to display the popover:
PreferencesViewController *pvc = [[PreferencesViewController alloc] init];
[pvc showHTMLHelp:html pointTo: rectangle background:[UIColor whiteColor]];
There is absolutely no problem with passing a C structure (or C primitive variable) to an Objective-C method. In fact, presentPopoverFromRect:inView:permittedArrowDirections:animated: takes a simple CGRect as you can tell by the header (or the documentation):
- (void)presentPopoverFromRect:(CGRect)rect
inView:(UIView *)view
permittedArrowDirections:(UIPopoverArrowDirection)arrowDirections
animated:(BOOL)animated;
Simply call it like this:
[popoverController presentPopoverFromRect:rectangle
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
And as Mar0ux already pointed out, it's CGRect, not GCRect. CG stands for Core Graphics.
May i ask you why you are sending an CGRect and casting it to 'id'? Where is the sense?! I would prefer to change your parameter type to CGRect too.
Kind regards.
I have a button I have created programmatically within a view controller. Once the button is pressed I want it to to use a method to create the popover programmatically.
The button which is created in the ViewDidLoad in my view controller.m
UIView *moreFundInfoView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 540, 620)];
[self.view addSubview:moreFundInfoView];
[moreFundInfoView setBackgroundColor:[UIColor RMBColor:#"b"]];
btnContact = [UIButton buttonWithType:(UIButtonTypeRoundedRect)];
[btnContact setFrame:CGRectMake(390, 575, contactButton.width, contactButton.height)];
btnContact.hidden = NO;
[btnContact setTitle:#"Contact" forState:(UIControlStateNormal)];
[moreFundInfoView addSubview:btnContact];
[btnContact addTarget:self action:#selector(showContactDetails:) forControlEvents:UIControlEventTouchUpInside];
Then I have the method I use when the button is pressed.
-(void) showContactDetails: (id) sender
{
UIViewController *popoverContent = [[UIViewController alloc]init];
UIView *popoverView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 200, 300)];
[popoverView setBackgroundColor:[UIColor RMBColor:#"b"]];
popoverContent.view = popoverView;
popoverContent.contentSizeForViewInPopover = CGSizeMake(200, 300);
UIPopoverController *contactPopover =[[UIPopoverController alloc] initWithContentViewController:popoverContent];
[contactPopover presentPopoverFromRect:btnContact.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES ];
[contactPopover setDelegate:self];
}
What am I missing here? Cause it runs fine, but as soon as I click the button the app crashes. I think it is a delegate issue, but I am not sure. Any advice would be appreciated.
I think this code will help you. You are certainly missing delegate methods
ViewController *viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navigationController];
popover.delegate = self;
popover.popoverContentSize = CGSizeMake(644, 425); //your custom size.
[popover presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections: UIPopoverArrowDirectionLeft | UIPopoverArrowDirectionUp animated:YES];
Just make sure you are not forgetting UIPopover Delegate methods or else application will definitely crash. It is mandatory.
UIViewController *controller = [[UIViewController alloc] init];
[view removeFromSuperview]; //view is a view which is displayed in a popover
controller.view = view;
UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:controller];
popover.delegate = self;
[popover presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionLeft animated:YES];
All I had to do was change the property from "retain" to "strong" in the .h file and it works, stopped the app from crashing.
Yes, changing property for "retain" to "strong" makes you to hold your picker view object.
I think the problem with your code was, UIPopoverController object gets deallocated automatically when method finishes.
making strong property gets you to strongly point an object.
I'm attempting to present a popoverView when a barButton is pressed. Unfortunately, the app crashes with the signal SIGABRT every time I try to call it. The "Empty.xib" does have a view designed in it. (As I'm using a barButton, I was unable to use the frame, if you have a workaround for that, please say so too).
- (IBAction)loadPopover:(id)sender
{
UIView *someView = [[UIView alloc] init];
UIViewController *someVC = [[UIViewController alloc] initWithNibName:#"Empty.xib" bundle:[NSBundle mainBundle]];
UIPopoverController *popoverController = [[UIPopoverController alloc] initWithContentViewController:someVC];
someView.frame = CGRectMake(0, 44, 320, 372);
someView.backgroundColor = [UIColor lightGrayColor];
popoverController.delegate = self;
self.popoverView = popoverController;
[self.popoverView presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
// CGRect popoverRect = [self.view convertRect:[btn frame] fromView:[btn superview]];
CGRect popoverRect = CGRectMake(0, 88, 320, 311);
popoverRect.size.width = MIN(popoverRect.size.width, 100);
[self.popoverView presentPopoverFromRect:popoverRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
Remove .xib part from initWithNibName:#"Empty.xib". Change line to this:
UIViewController *someVC = [[UIViewController alloc] initWithNibName:#"Empty" bundle:nil];
Edit:
From here -
The nib file name should not contain any leading path information.
Few suggestions here.
Check if the view's outlet is connected
Why do you need to allocate a UIView like the following? UIView *someView = [[UIView alloc] init];
Check if the sender is of type of UIBarButtonItem
What is the retain policy for self.popoverView? Check if it is retain or strong (if ARC)
Why do you present the popover two times?
Said this, here a simple snippet.
UIBarButtonItem* barButton = (UIBarButtonItem*)sender;
UIViewController *someVC = [[UIViewController alloc] initWithNibName:#"Empty" bundle:[NSBundle mainBundle]];
UIPopoverController *popoverController = [[UIPopoverController alloc] initWithContentViewController:someVC];
popoverController.delegate = self;
self.popoverView = popoverController;
[self.popoverView setPopoverContentSize:CGSizeMake(300, 200)];
[self.popoverView presentPopoverFromBarButtonItem:barButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
P.S. Make attention to memory if you don't use ARC.
Hope it helps.
How to add the UIView into UIPopoverViewController
-(void) buttonAction:(id)sender {
//build our custom popover view
UIViewController* popoverContent = [[UIViewController alloc]
init];
UIView* popoverView = [[UIView alloc]
initWithFrame:CGRectMake(0, 0, 200, 300)];
popoverView.backgroundColor = [UIColor whiteColor];
popoverContent.view = popoverView;
//resize the popover view shown
//in the current view to the view's size
popoverContent.contentSizeForViewInPopover =
CGSizeMake(200, 300);
//create a popover controller
self.popoverController = [[UIPopoverController alloc]
initWithContentViewController:popoverContent];
//present the popover view non-modal with a
//refrence to the button pressed within the current view
[self.popoverController presentPopoverFromRect:popoverButton.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:YES];
//release the popover content
[popoverView release];
[popoverContent release];
}
This will add the view to your UIPopoverViewController
You can check the following link below to get some idea as to how to do this
Are there examples of how to use UIPopoverController on iOS?
Try the below Code:
if (mycontroller == nil) {
MyController * viewController = [[MyController alloc] initWithNibName:#"ControllerView" bundle:nil];
mycontroller = viewController;
PopoverController = [[UIPopoverController alloc] initWithContentViewController:self.mycontroller];
PopoverController.delegate = self;
}
[PopoverController presentPopoverFromRect:CGRectMake(260, 120, 10, 10) inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];