iOS: How to persent a modalview as the UIPopover style - ios

I want to persent a modalwindow, I use the PresentModalViewController and set the ModalPresentationStyle to UIModalPresentationStyle.FormSheet.
But how to persent the window as a pop layer such as the UIpopover, it allows the users to dismiss the popwindow just touch the outside of the popwindow area.
BTW, how to modify the UIpopover dark frame and set the UIPopoverArrowDirection to nothing ?

The way that I do this is to implement the popoverControllerShouldDismissPopover method from the UIPopoverControllerDelegate in my parent view controller class, and just return a NO. This will prevent the popover from disappearing when the user taps somewhere other than on the popover.
#pragma mark - UIPopoverControllerDelegate
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
return NO;
}

Related

How to prevent UIPopoverPresentationController from being dismissed when clicking outside popover?

In my universal iOS 8 app, I am presenting a popover using using UIPopoverPresentationController as seen below from prepareForSegue:
FavoriteNameViewController *nameVC = segue.destinationViewController;
UIPopoverPresentationController *popPC = nameVC.popoverPresentationController;
popPC.delegate = self;
And with this delegate method.
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
In this particular case, I'm presenting a view controller that looks like an alert, but isn't.
Now my issue is that the user can click outside of this popover and it gets dismissed. There's no real problem with that except that's not how alerts work and I would like this to emulate an alert.
I see that UIPopoverControllerDelegate had a method called popoverControllerShouldDismissPopover:, but UIPopoverPresentationControllerDelegate doesn't have that method, and I believe I need to use the latter.
You need to set the popover controller's passthroughViews to nil and the view controller's modalInPopover to YES.
Try the following in your view
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
return YES;
}

iOS - UINavigationController - NavigationBar sliding in together with UIViewController

I have two UIViewControllers, A and B.
A is hiding the UINavigationBar and B is not.
When animating (with the default animation) from A to B, the navigation bar has to become visible. The navigation bar just pops in at some point (viewWillAppear or viewDidAppear) instead of sliding in with the UIViewController B.
When going back from B to A, the navigation bar is smoothly sliding back out.
How can I achieve the desired effect when animating from A to B?
In ViewController B, one has to simply do:
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear: animated];
[self.navigationController setNavigationBarHidden: NO animated: YES];
}
I wasn't aware that this also controls the animation while doing a full view controller transition. I thought it only controls animation the navigation bar out to the top and back in.
You can try the following:
Use a instance variable to do this:
self.navigationController setNavigationBarHidden:hide animated:animated];
_shouldHideStatusBar = hide;
And implement the following function:
- (BOOL)prefersStatusBarHidden{
return _shouldHideStatusBar;
}
The setNavigationBarHidden:animated function will automatically call prefersStatusBarHidden function. If it doesn't you can call it with the following UIViewController's method:
[self setNeedsStatusBarAppearanceUpdate];
And of course you can choose your status bar hiding animation style with:
- (UIStatusBarAnimation) preferredStatusBarUpdateAnimation {
return UIStatusBarAnimationSlide;
}
Let me know if this helps. Good luck!!
(I got this answer here: How to slide in/out statusBar and navigationBar simultaneously?)

How to call function on UIPopViewController dismiss in iPad

I am using UIPopViewController in iPad application,I can dismiss popviewcontroller using tap on screen.But,I am trying to call function for dismiss,is that possible?How can I call function?Please help me.
If you are trying to dismiss the popover programatically, you can simply call:
[popover dismissPopoverAnimated:YES];
If you are trying to detect whether a user has dismissed a popover by tapping on the screen, you can make use of the UIPopoverControllerDelegate method popoverControllerDidDismissPopover:
First, set the viewController which presents the popover as delegate:
popover.delegate = self;
Then implement the method:
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
//Perform necessary action here.
}
Have a look at the UIPopoverControllerDelegate reference here.

Prevent animation on UIPopover dismissed by tap outside?

When a user taps outside the popover, the dismissal is animated. Is there a way to set that dismissal animation to NO? I have googled and searched on Stack extensively.
The docs for UIPopover state:
When displayed, taps outside of the popover window cause the popover
to be dismissed automatically. 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. Taps inside the popover
window do not automatically cause the popover to be dismissed. Your
view and view controller code must handle actions and events inside
the popover explicitly and call the dismissPopoverAnimated: method as
needed.
I have implemented the dismissPopoverAnimated: method with NO and that works great for all the cases when I call that method.
The problem is when a user taps outside the popover to dismiss, dismissPopoverAnimated: is not called.
taps outside of the popover window cause the popover
to be dismissed automatically.
And that dismissal is animated. There seems to be no way to control that dismissal. I am using the popover to present a color picker for a drawing app. Taps to draw are not registered until the popover has finished animating out. This creates a noticeable delay as you are not able to draw immediately but must wait for the animation to complete.
I thought that - (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController could work but there is no way AFAIK to set the animation property in this method. Just return yes or no.
Is there a different method I can implement to be able to set the animation to NO?
In the view controller that presents your UIPopoverController, conform to the UIPopoverControllerDelegate protocol and implement the following delegate method. I just tested this and it does dismiss the popover without animation.
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
[self.myPopoverController dismissPopoverAnimated:NO];
return YES;
}
Just make sure that you have set the delegate of your popover controller to the view controller that implements this.
Swift 5
This will disable the animation, when we close the popOver by tapping outside.
extension YourViewController: UIPopoverPresentationControllerDelegate {
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool {
// to prevent animation, we need to dismiss it manuallly with animated: false
presentationController.presentingViewController.dismiss(animated: false, completion: nil)
return true
}
}
On iOS 9+ as by default modalPresentationStyle = .Popover you can implement this method to prevent dismiss clicking out
public func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool {
return false
}

UIPopover in storyboard

I have a UIViewcontroller, with a button. When I press the button it triggers a segue to a popover view (the segue is set through storyboard, not through the codes). When the popover is dismissed (by pressing outside of its bounds), I want the initial view controller to reload. how can I do that?
You can set the delegate of the popover controller in your prepareSegue: method and implement the delegate method popoverControllerDidDismissPopover: which will be called when the popver is dismissed.
You can get the popover controller with UIPopoverController *popover = [(UIStoryboardPopoverSegue *)segue popoverController]

Resources