UIPopoverPresentationController showing full screen modal popup always - ios

I am trying to show a view controller as UIPopoverPresentationController below the button or in center of window. But it is always showing as full window modal popup.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MySecondViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"Pop"];
// present the controller
// on iPad, this will be a Popover
// on iPhone, this will be an action sheet
controller.modalPresentationStyle = UINavigationControllerOperationPop;
[self presentViewController:controller animated:YES completion:nil];
controller.preferredContentSize = CGSizeMake(280, 230);
// configure the Popover presentation controller
UIPopoverPresentationController *popController = [controller popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionUp;
popController.delegate = self;
// in case we don't have a bar button as reference
popController.sourceView = self.showPop;
popController.sourceRect = CGRectMake(384, -120, 280, 230);
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}

Try this code it is working
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
SecondViewController *controller = [storyboard instantiateViewControllerWithIdentifier:#"pop"];
controller.modalPresentationStyle = UIModalPresentationPopover;
controller.preferredContentSize = CGSizeMake(280, 230);
// configure the Popover presentation controller
controller.popoverPresentationController.delegate = self;
controller.popoverPresentationController.permittedArrowDirections = UIPopoverArrowDirectionUp;
// in case we don't have a bar button as reference
controller.popoverPresentationController.sourceView = self.view;
controller.popoverPresentationController.sourceRect = CGRectMake(384, -120, 280, 230);
// controller.presentationController.delegate = self;
[self presentViewController:controller animated:YES completion:nil];

I have posted another question for the same question and i have resolved my issue. Here is the link of question:
UIPopoverPresentationController is showing full screen modal on iPhone
In ViewController.h Firstly make a property of UIPopoverPresenatationController.
#property(nonatomic,retain)UIPopoverPresentationController *dateTimePopover8;
Then to show PopOverPresentationcontroller
UINavigationController *destNav = [[UINavigationController alloc] initWithRootViewController:dateVC];
/*Here dateVC is controller you want to show in popover*/
dateVC.preferredContentSize = CGSizeMake(280,200);
destNav.modalPresentationStyle = UIModalPresentationPopover;
_dateTimePopover8 = destNav.popoverPresentationController;
_dateTimePopover8.delegate = self;
_dateTimePopover8.sourceView = self.view;
_dateTimePopover8.sourceRect = [sender frame];
destNav.modalPresentationStyle = UIModalPresentationPopover;
destNav.navigationBarHidden = YES;
[self presentViewController:destNav animated:YES completion:nil];
You must have noticed that we are presenting View Controller instead of presenting popOver.So we have to hide this in new way also.It hides automatically when we click on screen.
-(void)hideIOS8PopOver
{
[self dismissViewControllerAnimated:YES completion:nil];
}
We have to implement the delegate of UIPopoverPresenatationController in implementation file.Write below delegate method in implementation file.
- (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller {
return UIModalPresentationNone;
}

In Storyboard this is very easy. Just control drag from the control that will trigger the action (say a UIBarButton or a normal button) to the storyboard view controller (if root view of Navigation controller, drag to the navigation controller).
Select the segue and change the Kind in the attribute inspector to "Present Modally", presentation: Form sheet (if you want it to show at the centre), select the transition type you want (default is cool).

As #Lukas1 mentioned above, you should conform UIPopoverPresentationControllerDelegate and implement adaptivePresentationStyle method (which is actually defined in UIAdaptivePresentationControllerDelegate protocol, UIPopoverPresentationControllerDelegate parent class) and return .none
And here's implementation in Swift5 :
extension ViewController: UIPopoverPresentationControllerDelegate {
func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
return UIModalPresentationStyle.none
}
}

Related

pushing a view controller from presented popup view controller

I am presenting a view controller as a popup and in the popup view controller i have a button , onclick of that button i am trying to push a view controller but nothing happens on click.How to do this?
Presnting the view controller as a popup
- (IBAction)sendOTPAction:(id)sender {
HMResetPasswordViewController *resetPassword = [self.storyboard instantiateViewControllerWithIdentifier:#"HMResetPasswordViewController"];
// configure the Popover presentation controller
resetPassword.modalPresentationStyle = UIModalPresentationPopover;
resetPassword.preferredContentSize = CGSizeMake(self.view.frame.size.width-10, 375);
resetPassword.popoverPresentationController.delegate = self;
resetPassword.popoverPresentationController.permittedArrowDirections = 0;
resetPassword.popoverPresentationController.sourceView = self.view;
resetPassword.popoverPresentationController.sourceRect = CGRectMake(CGRectGetMidX(self.view.bounds), CGRectGetMidY(self.view.bounds),0,0);
[self presentViewController:resetPassword animated:YES completion:nil];
}
Trying to push the view controller from popup view controloer
- (IBAction)resetButtonAction:(id)sender {
HMLoginViewController *HMLoginViewController= [self.storyboard instantiateViewControllerWithIdentifier:#"HMLoginViewController"];
[self.navigationController pushViewController:HMLoginViewController animated:YES];
}
After presenting, if you want to use navigation stack then you have to create new navigation controller :
- (IBAction)resetButtonAction:(id)sender {
HMLoginViewController *HMLoginViewController= [self.storyboard instantiateViewControllerWithIdentifier:#"HMLoginViewController"];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:HMLoginViewController];
[self presentViewController:nc animated:YES];
}
After HMLoginViewController, now you can push to other UIViewController

UIPopoverPresentationController is showing full screen modal on iPhone

On iPad UIPopoverPresentationController working fine but on iPhone it is always showing full window modal popup. i am using following code:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MySecondViewController *contentVC = [storyboard instantiateViewControllerWithIdentifier:#"Pop"];
contentVC.modalPresentationStyle = UINavigationControllerOperationPop; // 13
UIPopoverPresentationController *popPC = contentVC.popoverPresentationController; // 14
contentVC.popoverPresentationController.sourceRect =CGRectMake(100, 130, 280, 230);
self.navigationController.preferredContentSize = CGSizeMake(200, self.parentViewController.childViewControllers.lastObject.preferredContentSize.height-100);
//self.showPop.frame; // 15
contentVC.popoverPresentationController.sourceView =
self.showPop; // 16
popPC.permittedArrowDirections = UIPopoverArrowDirectionAny; // 17
popPC.delegate = self; //18
[self presentViewController:contentVC animated:YES completion:nil];
-(UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller {
return UIModalPresentationNone;
}
In ViewController.h Firstly make a property of UIPopoverPresenatationController.
#property(nonatomic,retain)UIPopoverPresentationController *dateTimePopover8;
Then to show PopOverPresentationcontroller
UINavigationController *destNav = [[UINavigationController alloc] initWithRootViewController:dateVC];/*Here dateVC is controller you want to show in popover*/
dateVC.preferredContentSize = CGSizeMake(280,200);
destNav.modalPresentationStyle = UIModalPresentationPopover;
_dateTimePopover8 = destNav.popoverPresentationController;
_dateTimePopover8.delegate = self;
_dateTimePopover8.sourceView = self.view;
_dateTimePopover8.sourceRect = [sender frame];
destNav.modalPresentationStyle = UIModalPresentationPopover;
destNav.navigationBarHidden = YES;
[self presentViewController:destNav animated:YES completion:nil];
You must have noticed that we are presenting View Controller instead of presenting popOver.So we have to hide this in new way also.It hides automatically when we click on screen.
-(void)hideIOS8PopOver
{
[self dismissViewControllerAnimated:YES completion:nil];
}
We have to implement the delegate of UIPopoverPresenatationController in implementation file.Write below delegate method in implementation file.
- (UIModalPresentationStyle) adaptivePresentationStyleForPresentationController: (UIPresentationController * ) controller {
return UIModalPresentationNone;
}
Popover controllers are for use exclusively on iPad devices.
Edit: As stated by Soberman, since iOS 8 it is possible to present popovers on iPhone using public APIs, so this answer is probably not relevant anymore.
As stated in Apple's documentation on UIPopoverController:
Popover controllers are for use exclusively on iPad devices.
So there is no way to use this class in iPhone application unfortunately. But there are a couple of custom third-party implementations of the functionality provided by UIPopoverController which add iPhone support and more. See https://github.com/50pixels/FPPopover for example.
Edit: There also is another highly customizable popover implementation for both iPhone/iPad worth checking out: https://github.com/nicolaschengdev/WYPopoverController.

How do you programmatically configure and present a popover on iPhone in iOS 8+

How can you present a UIViewController in a popover on iPhone (all sizes and orientations), in iOS 8 using only Objective-C code, no Story Boards or other Interface Builder artifacts.
In iOS 8, you can configure any view controller to be displayed as a popover, like so:
UIViewController* controller = ...; // your initialization goes here
// set modal presentation style to popover on your view controller
// must be done before you reference controller.popoverPresentationController
controller.modalPresentationStyle = UIModalPresentationPopover;
controller.preferredContentSize = CGSizeMake(150, 300);
// configure popover style & delegate
UIPopoverPresentationController *popover = controller.popoverPresentationController;
popover.delegate = controller;
popover.sourceView = sourceView;
popover.sourceRect = CGRectMake(150,300,1,1);
popover.permittedArrowDirections = UIPopoverArrowDirectionAny;
// display the controller in the usual way
[self presentViewController:controller animated:YES completion:nil];
So that it displays as a popover on iPhone, add this to the UIPopoverPresentationControllerDelegate delegate of the popover (that you set above):
- (UIModalPresentationStyle)adaptivePresentationStyleForPresentationController:(UIPresentationController *)controller
{
return UIModalPresentationNone;
}

How to open side menu not open by button click?

I am using ECsliding controller for slide menu.swipe gestrure working good in my case but when click button nothing happened.
My case is:
After two screen, I wanted to show slide menu so i have set ECSlide like belowe in my second screen and so far everything ok.
In third view controller I set a button to show menu.Button get clicked but menu not open.
- (void)viewWillAppear:(BOOL)animated{
if (![self.slidingViewController.underLeftViewController isKindOfClass:[LeftViewController class]]) {
self.slidingViewController.underLeftViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"LeftViewController"];
}
[self.navigationController setNavigationBarHidden:YES animated:YES];
if ([self.checkStr isEqualToString:#"1"])
{
//provider
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main"
bundle: nil];
LeftViewController *leftMenu = (LeftViewController*)[mainStoryboard
instantiateViewControllerWithIdentifier: #"LeftViewController"];
// Create your menu view controller
ProfileController *leftMenuONE = (ProfileController*)[mainStoryboard
instantiateViewControllerWithIdentifier: #"ProfileControllerID"];
// configure top view controller
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:leftMenuONE];
self.slidingViewController = [ECSlidingViewController slidingWithTopViewController:navigationController];
self.slidingViewController.underLeftViewController = leftMenu;
// enable swiping on the top view
[navigationController.view addGestureRecognizer:self.slidingViewController.panGesture];
// configure anchored layout
self.slidingViewController.anchorLeftRevealAmount = 250.0;
[self.navigationController pushViewController:self.slidingViewController animated:YES];
}
else
{
//user
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main"
bundle: nil];
LeftViewController *leftMenu = (LeftViewController*)[mainStoryboard
instantiateViewControllerWithIdentifier: #"LeftViewController"];
// Create your menu view controller
UserProfileController *leftMenuONE = (UserProfileController*)[mainStoryboard
instantiateViewControllerWithIdentifier: #"UserProfileControllerID"];
// configure top view controller
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:leftMenuONE];
self.slidingViewController = [ECSlidingViewController slidingWithTopViewController:navigationController];
self.slidingViewController.underLeftViewController = leftMenu;
// enable swiping on the top view
[navigationController.view addGestureRecognizer:self.slidingViewController.panGesture];
// configure anchored layout
self.slidingViewController.anchorLeftRevealAmount = 250.0;
[self.navigationController pushViewController:self.slidingViewController animated:YES];
}
}
LeftViewController is my menu view controller.
Third view controller will load based condition.example if string is one,it will go to one view controller otherwise anther view controller.
Thirdview.h
- (IBAction)menuAction:(id)sender
{
[self.slidingViewController anchorTopViewToRightAnimated:YES];
}
-(void)viewWillAppear:(BOOL)animated
{
if (![self.slidingViewController.underLeftViewController isKindOfClass:[LeftViewController class]]) {
self.slidingViewController.underLeftViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"LeftViewController"];
}
}

How to call a View Controller programmatically?

I have looked at all the tutorials I can find on this one, and I still don't have the answer. I need to call another view from the code. I am using UIStoryboards. I have changed the view many times by control-dragging from UIButtons, but now it must be from the code. I am trying to call the info page from the main menu if it is the first time the user has opened the app. I cannot seem to find a way to change the views from the code, however. All my views are controlled by the same files (ViewController2). The identifier of my main menu is ViewControllerMain, and the identifier of the info page is ViewControllerInfo. First I tried this:
[ViewControllerMain presentViewController: ViewControllerInfo
animated:YES
completion: NULL];
Then I tried making different UIViewControllers for each and saying:
[ViewController2 presentViewController: ViewController
animated:YES
completion: NULL];
Neither worked. For the first one, it says:
Use of undeclared identifier ViewControllerMain.
In the second one, it says:
unexpected interface name 'ViewController': expected identifier.
What can I do?
To create a view controller:
UIViewController * vc = [[UIViewController alloc] init];
To call a view controller (must be called from within another viewcontroller):
[self presentViewController:vc animated:YES completion:nil];
For one, use nil rather than null.
Loading a view controller from the storyboard:
NSString * storyboardName = #"MainStoryboard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"IDENTIFIER_OF_YOUR_VIEWCONTROLLER"];
[self presentViewController:vc animated:YES completion:nil];
Identifier of your view controller is either equal to the class name of your view controller, or a Storyboard ID that you can assign in the identity inspector of your storyboard.
You need to instantiate the view controller from the storyboard and then show it:
ViewControllerInfo* infoController = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerInfo"];
[self.navigationController pushViewController:infoController animated:YES];
This example assumes that you have a navigation controller in order to return to the previous view. You can of course also use presentViewController:animated:completion:. The main point is to have your storyboard instantiate your target view controller using the target view controller's ID.
Swift
This gets a view controller from the storyboard and presents it.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let secondViewController = storyboard.instantiateViewController(withIdentifier: "secondViewControllerId") as! SecondViewController
self.present(secondViewController, animated: true, completion: nil)
Change the storyboard name, view controller name, and view controller id as appropriate.
You can call ViewController this way, If you want with NavigationController
1.In current Screen : Load new screen
VerifyExpViewController *addProjectViewController = [[VerifyExpViewController alloc] init];
[self.navigationController pushViewController:addProjectViewController animated:YES];
2.1 In Loaded View : add below in .h file
#interface VerifyExpViewController : UIViewController <UINavigationControllerDelegate>
2.2 In Loaded View : add below in .m file
#implementation VerifyExpViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.delegate = self;
[self setNavigationBar];
}
-(void)setNavigationBar
{
self.navigationController.navigationBar.backgroundColor = [UIColor clearColor];
self.navigationController.navigationBar.translucent = YES;
[self.navigationController.navigationBar setBackgroundImage:[UIImage imageNamed:#"B_topbar.png"] forBarMetrics:UIBarMetricsDefault];
self.navigationController.navigationBar.titleTextAttributes = #{NSForegroundColorAttributeName: [UIColor whiteColor]};
self.navigationItem.hidesBackButton = YES;
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Btn_topback.png"] style:UIBarButtonItemStylePlain target:self action:#selector(onBackButtonTap:)];
self.navigationItem.leftBarButtonItem.tintColor = [UIColor lightGrayColor];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Save.png"] style:UIBarButtonItemStylePlain target:self action:#selector(onSaveButtonTap:)];
self.navigationItem.rightBarButtonItem.tintColor = [UIColor lightGrayColor];
}
-(void)onBackButtonTap:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
-(IBAction)onSaveButtonTap:(id)sender
{
//todo for save button
}
#end
Hope this will be useful for someone there :)
There's 2 ways you can do this:
1, Create a segue to your ViewController in your Storyboard as explained in my answer here: How to perform a segue that is not related to user input in iOS 5?
2, Give your ViewController and identifier and call it using the code in my answer here: Call storyboard scene programmatically (without needing segue)?
main logic behind this is_,
NSString * storyboardIdentifier = #"SecondStoryBoard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardIdentifier bundle: nil];
UIViewController * UIVC = [storyboard instantiateViewControllerWithIdentifier:#"YourviewControllerIdentifer"];
[self presentViewController:UIVC animated:YES completion:nil];
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone_iOS7" bundle:nil];
AccountViewController * controller = [storyboard instantiateViewControllerWithIdentifier:#"accountView"];
// [self presentViewController:controller animated:YES completion:nil];
UIViewController *topRootViewController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topRootViewController.presentedViewController)
{
topRootViewController = topRootViewController.presentedViewController;
}
[topRootViewController presentViewController:controller animated:YES completion:nil];
Import the view controller class which you want to show and use the following code
KartViewController *viewKart = [[KartViewController alloc]initWithNibName:#"KartViewController" bundle:nil];
[self presentViewController:viewKart animated:YES completion:nil];

Resources