Don't Dismiss UIPopoverController when tap off - objective-c

after a bit of searching, I couldn't find an answer to something that seems like it would be useful to many.
Is there a way to make a UIPopoverController not dismiss when the user clicks somewhere on the outside? I want the user to have to use a cancel button (Yes, i realize this probably violates Apple's HIG somehow, but it's a rare case and makes sense from a User experience perspective).
Thanks for any help.

Just set the modalInPopover property on the UIViewController being displayed in the UIPopoverController.
popover = [[UIPopoverController alloc] initWithContentViewController:content];
content.modalInPopover = YES;
[popover presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
Be aware that, as of iOS5, you have to set modalInPopover inside of -viewDidAppear.

You can do hit-tests on where the tap occurred and in your popover's delegate return NO. - (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController

So, I realize this is an old question. However, there's an easier answer for anyone searching for a solution today.
If you use a Storyboard Segue, you can set the passthrough property on the segue allowing interaction with other objects in the view. If you do so, clicking outside of the bounds of the popover won't close the popover.
Here's some more info:
What are Anchor and Passthrough used for in popover segues?
And here's a excerpt from the Apple documentation:
To allow the user to interact with the specified views and not dismiss
the popover, you can assign one or more views to the passthroughViews
property.

Related

Getting reference to UIPopoverController from it's contentViewController

Hm. While writing subject, I've found that this is impossible (according to this thread).
My goal is pretty simple:
I have popover and button inside it. I want to show something bigger than current size of popover on button touchedUpInside, so I need resize popover. But since I can't get the reference to the popover, I need to keep reference to popover's "super view controller". That's just ugly.
So now I'm looking for some more elegant solutions.
UPDATE: That's ugly because I've ended with that expression:
[(UIPopoverController*)[[(AppDelegate*)[[UIApplication sharedApplication] delegate] calendarViewController]
performSelector: #selector(popover)]
setPopoverContentSize:viewFrame.size animated: YES];
Just to resize simple popover :(

Interact with other views while a popover is active

I have a toolBar and I have setup two UIBarButtonItem on it. Both UIBarButtonItem are containing UIButtons as their customViews.
I activate a popover for their Touch Up Inside event as below,
[popover1 presentPopoverFromBarButtonItem:buttonItem1 permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
I have another UIButton named clearFilters inside the main view. (Also this is the view which is containing the above toolBar.) I have declared a method for clearFilters button's Touch Up Inside event.
My problem is,
I can not interact with the clearFilters button while a popover is active. So, I'm looking for a solution to interact with this clearFilters button, while a popover is active.
I tried by adding passthroughViews property for a popover as below and it do not work as I expect.
popover1.passthroughViews = [NSArray arrayWithObject:clearFiltersButton];
What could be the reason. As the documentation has mentioned I can not see any issue.
I expect if the above things are correct, then the Touch Up Inside event of the the clearFilters button's should be fire up.
So, please show me if there is any issue or a necessary way to work on this thing.
I'm working on XCode4 and iOS 4.3.
Thanks.
The UIPopoverController documentation reveals why the other bar buttons can be tapped while the popover is visible:
“When presenting the popover, this method adds the toolbar that owns the button to the popover’s list of passthrough views.”
Try querying and logging the popover’s passthrough views. Does it already have things in it? Perhaps something like this would work?
myPopover.passthroughViews = [myPopover.passthroughViews arrayByAddingObject:clearFilters];
I haven’t tested this code, but it’s worth a try.

Not rotating only one view in a tab bar view controller

I know this question has been kind of asked and have looked into the solutions that others have posted but still feel quite confused on the topic so I apologize if this really is a "noob" question.
So I have a tab bar view controller and I have 2 views that should autorotate and one that never should. My understanding is that shouldAutorotateToInterfaceOrientation needs to always return YES; in order for any view controllers to autorotate. So if this is the case, how would I get only one to NOT rotate but keep the orders rotating?
Thank you very much!
P.S. I tried this from a different post found here: How to prevent the view controllers in a tab bar controller from rotating? but with no luck. The answer from that post is posted below
"This is a commonly reported "bug" - however a good workaround is to force the shouldAutorotateToInterfaceOrientation: selector to be triggered as follows:"
- (void)viewDidAppear:(BOOL)animated {
UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];
}
The behavior you're aiming for conflicts with the rotation rules of UITabBarControllers. You mentioned it yourself:
shouldAutorotateToInterfaceOrientation needs
to always return YES in order for any view controllers to autorotate.
But what you want is for one of the view controllers to return NO, which violates that rule. So to answer your question, you will have to implement your own custom view controller container (or a custom view).
There's a good reason this restriction was placed added to UITabBarControllers. Tabs with different rotation rules will be annoying to user since the screen will keep rotating on them each time they change tabs.
Now if I were you, I'll allow all my tabs to rotate, then present the non-rotating view as a modal view.

Confusing behavior from UIPopoverController

I'm trying to set up a popover to appear that displays a UIDatePicker when I press a button, however I'm getting some very confusing behavior. I created a view controller that housed nothing but the UIDatePicker, wired one up in the class i needed it in, and added it to a new UIPopoverController like this:
self.timePickerPopoverController = [[UIPopoverController alloc] initWithContentViewController:self.timePickerViewController];
then I present it like so:
[timePickerPopoverController presentPopoverFromRect:prepTimeButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
(prepTimeButton being the button that was pressed). However, I just get the following result:
Instead of it displaying next to the button that was pressed and at the target size (it's way too tall right now; should only be the size of the date picker). I also tried giving it a custom view of the proper location and size in which to display, but that didn't help much (just shifted the popover to the right half of the screen). What am I doing wrong and how do I fix it?
Is self.view the direct superview of prepTimeButton? Perhaps prepTimeButton is nested in a subview, in that case you'd need to use that as the inView: parameter (or convert the coordinates).
Did you set the contentSizeForViewInPopover property of your view controller?
Make sure to set both contentSizeForViewInPopover on the internal view controller and popoverContentSize on the UIPopoverController itself.

IPad dismiss Keyboard without knowing which Textfield opened it

Is there a way to do a general resignFirstResponder to hide the keyboard regardless of what textfield/view/etc calls it?
Reason is I have a lot of textfields on my view and don't want to have to resignFirstResponder for all textfields to hide the keyboard. Just want a general
[self resignFirstResponder].
Any ideas?
Thanks in advance
I know that this has already been marked as answered, but for those that run into this like I did you can just use the following method on the view that contains the textfields.
- (BOOL)endEditing:(BOOL)force
This method looks at the current view and its subview hierarchy for the text field that is currently the first responder. If it finds one, it asks that text field to resign as first responder. If the force parameter is set to YES, the text field is never even asked; it is forced to resign. UIView Documentation
[self.view endEditing:YES];
it will hide keyboard when we click on view.
You can dismiss the keyboard without any reference to UITextfield / UITextView with help of below code:
[[[UIApplication sharedApplication] keyWindow] endEditing:YES];
this will dismiss the keyboard globally without the reference.
hope this will help you.
The easiest way to do this is to have a method for whenever you want to dismiss the keyboard that looks like this:
-(void)dismissKeyboard {
[firstField becomeFirstResponder];
[firstField resignFirstResponder];
}
You can check these questions:
Is it possible to make the iPhone keyboard invisible / remove it without resigning first responder?
Hide Input Keyboard on iPhone Without Knowing First Responder?
In summary:
You can call becomeFirstResponder on some other thing that you choose. It could be a UIViewController or a UIView. I had a similar problem before, I needed to make my keyboard go away when I was pushing my view controller back to its caller, without knowing which textfield was the first responder. Then, on viewWillAppear of my view controller which I was returning back, I called [self becomeFirstResponder] and the keyboard of the pushed view was gone. Because this made whichever text field was it loose being the first responder
In my own app when I had more than one text field and would like to make the keyboard go away regardless which of the fields called it, I would just wrote a method and let each and every of them resignFirstResponder.
I assume that as a programmer, you should have the clear knowledge how many text fields are on your view controller and how you can access them, otherwise it'll get messed up and you app won't look good... :-P