ViewController content size doesn't change popover size - ios

The popover's preferred size is only works if the height is greater than 320.
I have searched a lot to solve this issue. But didn't find any answer. Is there any minimum size that the popover should satisfy in iPad? If not, what i'm missing?
Code:
UIViewController *viewController = [subStoryboard instantiateViewControllerWithIdentifier:SMFormViewControllerSBID];
controller = [[UINavigationController alloc] initWithRootViewController:viewController];
SMFormViewController *formViewController = (SMFormViewController *)controller.topViewController;
formViewController.modalPresentationStyle = UIModalPresentationPopover;
formViewController.preferredContentSize = CGSizeMake(375, 320);
popController = [controller popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionLeft;
popController.delegate = self;
popController.sourceView = tblDocDetails;
NSInteger section = [tblDocDetails numberOfSections] - 1;
CGRect rectCustomLoc = [tblDocDetails rectForFooterInSection:section];
popController.sourceRect = CGRectMake(rectCustomLoc.origin.x, rectCustomLoc.origin.y, 130, rectCustomLoc.origin.y/2);
[self presentViewController:controller animated:YES completion:nil];
Note:
I tried, adaptivePresentationStyleForPresentationController: & adaptivePresentationStyleForPresentationController: to return UIModalPresentationNone.

I tried the following:
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
UIButton *btnOpen = [UIButton buttonWithType:UIButtonTypeCustom];
[btnOpen setFrame:CGRectMake(100, 100, 100, 44)];
[btnOpen setTitle:#"POP" forState:UIControlStateNormal];
[btnOpen setBackgroundColor:[UIColor grayColor]];
[btnOpen addTarget:self action:#selector(btnOpen:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btnOpen];
}
- (void)btnOpen:(id)sender {
UIView *sourceView = (UIButton *)sender;
UIViewController *vc = [[UIViewController alloc] initWithNibName:nil bundle:nil];
vc.modalPresentationStyle = UIModalPresentationPopover;
vc.preferredContentSize = CGSizeMake(150, 150);
[self presentViewController:vc animated:YES completion:nil];
UIPopoverPresentationController *popVc = vc.popoverPresentationController;
popVc.permittedArrowDirections = UIPopoverArrowDirectionLeft;
popVc.sourceView = sourceView;
popVc.sourceRect = sourceView.bounds;
}
and it resulted in this (iPad Air 2, iOS 11.2):
Here is a solution based on your example, I think your use of GCD to show the popover might be causing the issue...
UIViewController *viewController = [subStoryboard instantiateViewControllerWithIdentifier:SMFormViewControllerSBID];
controller = [[UINavigationController alloc] initWithRootViewController:viewController];
controller.modalPresentationStyle = UIModalPresentationPopover;
controller.preferredContentSize = CGSizeMake(375, 320);
[self presentViewController:controller animated:YES completion:nil];
popController = [controller popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionLeft;
popController.delegate = self;
popController.sourceView = tblDocDetails;
NSInteger section = [tblDocDetails numberOfSections] - 1;
CGRect rectCustomLoc = [tblDocDetails rectForFooterInSection:section];
popController.sourceRect = CGRectMake(rectCustomLoc.origin.x, rectCustomLoc.origin.y, 130, rectCustomLoc.origin.y/2);

My popover sometimes doesn't visible, because of the sourceRect was incorrect.
Since I embedded ViewController in a Navigation Controller, preferredContentSize should set to Navigation Controller.
controller.preferredContentSize = CGSizeMake(375, 100);
& in ViewController:
self.navigationController.preferredContentSize = contentsize;
And Changed sourceRect to:
CGRect rectCustomLoc = [table rectForFooterInSection:section];
rectCustomLoc.size.width = sender.frame.size.width;
popController.sourceRect = rectCustomLoc;

Related

Different navigation bar behaviour between CABTMIDILocalPeripheralViewController and CABTMIDICentralViewController

I am struggling to understand why the following views, one for CABTMIDILocalPeripheralViewController and the other for CABTMIDICentralViewController show different behaviour in my iOS app (written in Objective-C)
- (IBAction)configureCentral:(id)sender
{
CABTMIDICentralViewController *viewController = [CABTMIDICentralViewController new];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController]; // this will present a view controller as a popover in iPad and modal VC on iPhone
viewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(doneAction:)];
navController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popC = navController.popoverPresentationController;
popC.permittedArrowDirections = UIPopoverArrowDirectionAny;
popC.sourceRect = [sender frame];
viewController.preferredContentSize = CGSizeMake(320., 400.);
popC.backgroundColor = [UIColor darkGrayColor];
viewController.view.backgroundColor = [UIColor darkGrayColor];
UIButton *button = (UIButton *)sender;
popC.sourceView = button.superview;
[self presentViewController:navController animated:NO completion:nil];
}
Opens a popup view on an iOS device, which does not show any 'done' button to dismiss the view.
CABTMIDICentralViewController shows no button to close/dismiss the view
While on an iPad tapping outside the view will close it, on an iPhone the view takes the size of the screen and exiting/closing becomes impossible.
The same code used for the CABTMIDILocalPeripheralViewController works as expected.
- (IBAction)configureLocalPeripheral:(id)sender
{
CABTMIDILocalPeripheralViewController *vController = [[CABTMIDILocalPeripheralViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vController];
vController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
target:self
action:#selector(doneWithPeripheral:)];
navController.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController *popC = navController.popoverPresentationController;
popC.permittedArrowDirections = UIPopoverArrowDirectionAny;
popC.sourceRect = [sender frame];
vController.preferredContentSize = CGSizeMake(320., 400.);
popC.backgroundColor = [UIColor grayColor];
vController.view.backgroundColor = [UIColor darkGrayColor];
UIButton *button = (UIButton *)sender;
popC.sourceView = button.superview;
[self presentViewController:navController animated:NO completion:nil];
}
CABTMIDILocalPeripheralViewController has a 'done' button
What is going wrong here? I have tested to make the views wider to see whether available space in the Navigation bar would have caused this.
Thanks.

View shifted across to the right

I am trying to figure out why this tableView is shifted across to the right, it appears in every view the app uses, yet the app itself displays fine, it's only when the tableView appears is everything shifted out of the screen.
I believe the initializing is here;
- (void)viewDidLoad {
[super viewDidLoad];
NSLog(#"Lets load the frame");
CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view setFrame: frame];
self.contentSizeForViewInPopover = CGSizeMake(320, 480);
m_mywork = nil;
dataArray = [LoadSessionController loadTableData:YES];
}
Here is the initializing from another class;
on iPad display is perfect.
- (void) ShowInitialMenu
{
InitialMenuController *MewMgrController = [[InitialMenuController alloc] initWithStyle:UITableViewStyleGrouped];
MewMgrController.delegate = self;
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController: MewMgrController];
if(![ColorSplashAppDelegate isiPad]){
[self presentViewController:navController animated:YES completion:nil];
}
else{
UIPopoverController* popover = [[UIPopoverController alloc] initWithContentViewController:navController];
popover.delegate = self;
[popover presentPopoverFromRect:CGRectMake(30.0, 940.0, 30.0, 480.0)
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionDown
animated:YES];
ColorSplashAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
appDelegate.popoverController = popover;
}
[navController release];
[MewMgrController release];
[self enableUserAction:YES];
}
Try This.
-(void)viewDidLayoutSubviews
{
CGRect frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
[self.view setFrame: frame];
self.contentSizeForViewInPopover = CGSizeMake(320, 480);
m_mywork = nil;
}

UIPopoverPresentationController width and height not setting

I am trying to present a popover controller but for some reason I can't get the width/height of the popover to set correctly. Here's the code I am using:
Here's my code:
UIStoryboard* myStoryboard = self.storyboard;
ScenarioPopOver* popOver = (ScenarioPopOver*)[myStoryboard instantiateViewControllerWithIdentifier:#"scenarioPopover"];
popOver.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:popOver animated:YES completion:nil];
// configure the Popover presentation controller
UIPopoverPresentationController *popController = [popOver popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionUp;
popController.delegate = self;
// in case we don't have a bar button as reference
popController.sourceView = self.view;
popController.sourceRect = CGRectMake(self.view.center.x - 25.0, 10.0, 50.0, 50.0);
But the popover keep coming out like this:
Just in case someone stumbles across this issue. I was trying to set the preferredContentSize on the UIPopoverPresentationController and not the UIViewController within it. Correct code is below:
UIStoryboard* myStoryboard = self.storyboard;
ScenarioPopOver* popOver = (ScenarioPopOver*)[myStoryboard instantiateViewControllerWithIdentifier:#"scenarioPopover"];
popOver.modalPresentationStyle = UIModalPresentationPopover;
[self presentViewController:popOver animated:YES completion:nil];
// configure the Popover presentation controller
UIPopoverPresentationController *popController = [popOver popoverPresentationController];
popController.permittedArrowDirections = UIPopoverArrowDirectionUp;
popController.delegate = self;
popOver.preferredContentSize = CGSizeMake(400.0, 300.0);
// in case we don't have a bar button as reference
popController.sourceView = self.view;
popController.sourceRect = CGRectMake(self.view.center.x - 150.0, 10.0, 0.0, 0.0);

UIPopoverController for iphone in ios8 shows white screen

Using UIPopovercontroller below ios8.0 in iphone working fine with this code. But in ios8 it display white screen.
Code :
pickerController = [[UIViewController alloc] init];
UIView *viewV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 160)];
[viewV setBackgroundColor:[UIColor clearColor]];
popOverController = [[UIPopoverController alloc] initWithContentViewController:pickerController];
popOverController.popoverContentSize = CGSizeMake(150, 160);
[popOverController setDelegate:self];
CGRect ImageBtnFrame = [self.view convertRect:sender.frame fromView:self.view];
[popOverController presentPopoverFromRect:ImageBtnFrame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
Any alternative for ios8, need suggestion.
According to 2014 WWDC, in the 30 minute mark, the right answer is:
- (void) tapButton:(id) sender
{
MyViewControllerClass * vc = [[MyViewControllerClass alloc] init];
vc.modalPresentationStyle = UIModalPresentationPopover;
UIPopoverPresentationController * popOverController = vc.popoverPresentationController;
[popOverController setDelegate:self];
popOverController.sourceView = sender;
popOverController.sourceRect = ((UIButton*)sender).frame;
popOverController.permittedArrowDirections = UIPopoverArrowDirectionUp;
[self presentViewController:vc
animated:YES
completion:nil];
}
Notice that the accepted answer has some problems like:
Not setting the modalPresentationStyle
Presenting the UIPopoverPresentationController * instead of the UIViewController
Try to use the new iOS 8 API for popovers.
pickerController = [[UIViewController alloc] init];
UIView *viewV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 160)];
[viewV setBackgroundColor:[UIColor clearColor]];
UIPopoverPresentationController *popOverController = pickerController .popoverPresentationController;
popOverController.popoverContentSize = CGSizeMake(150, 160);
[popOverController setDelegate:self];
popOverController.sourceView = self.view;
popOverController.sourceRect = sender.frame;
popOverController.permittedArrowDirections = UIPopoverArrowDirectionUp;
[self presentViewController:popOverController
animated:YES
completion:nil];
That will cause on iOS 8. So, I recommended to use following Github library.
https://github.com/skywinder/ActionSheetPicker-3.0 or you can write code base on iOS version.
if (OLDER_THAN_IOS_8) {
// Your regular code
pickerController = [[UIViewController alloc] init];
UIView *viewV = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 150, 160)];
[viewV setBackgroundColor:[UIColor clearColor]];
popOverController = [[UIPopoverController alloc] initWithContentViewController:pickerController];
popOverController.popoverContentSize = CGSizeMake(150, 160);
[popOverController setDelegate:self];
CGRect ImageBtnFrame = [self.view convertRect:sender.frame fromView:self.view];
[popOverController presentPopoverFromRect:ImageBtnFrame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
} else {
// New Code that support iOS -8 using UIPopoverPresentationController
// Checkout #AndreasZ answer for the same
}

Greedy UITabBarController?

I'm making a custom UIViewController which holds to sub view controllers. They are put inside the main view controller this way:
- (void) setHeaderViewController:(UIViewController *)vc
{
[self setViewController:vc isHeader:YES];
_headerViewController = vc;
}
- (void) setDetailViewController:(UIViewController *)vc
{
[self setViewController:vc isHeader:NO];
_detailViewController = vc;
}
- (void) setViewController:(UIViewController*) viewController isHeader:(BOOL)isHeader
{
UIViewController* viewControllerRef = ((isHeader) ? _headerViewController : _detailViewController);
if(viewControllerRef == viewController)
return;
const CGSize selfSize = self.view.frame.size;
CGRect viewFrame;
if (isHeader)
{
viewFrame = CGRectMake(0, 0, selfSize.width, 150);
}
else
{
viewFrame = CGRectMake(0, 150, selfSize.width, selfSize.height-150);
}
UIView* viewControllerView = viewController.view;
[viewControllerView setFrame:viewFrame];
[viewControllerView setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight | ((isHeader) ? UIViewAutoresizingFlexibleBottomMargin : UIViewAutoresizingFlexibleTopMargin))];
[self.view addSubview:viewControllerView];
}
If I put two UIViewControllers inside of each sub view controller slot, the sizes defined in the method is respected. However, when putting a UITabBarController, it gets greedy and occupies the whole space:
UIViewController *vc = [[WIFCustomerDetailHeaderViewController alloc] initWithNibName:#"WIFCustomerDetailHeaderViewController" bundle:nil];
[self setHeaderViewController:vc];
UIViewController *vc1 = [[UIViewController alloc] init];
vc1.title = #"Personal Data";
vc1.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Personal Data" image:nil tag:0];
vc1.view.backgroundColor = [UIColor redColor];
vc1.view.frame = CGRectMake(0,400,100,100);
UIViewController *vc2 = [[UIViewController alloc] init];
vc2.title = #"Diagnosis";
vc2.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Diagnosis" image:nil tag:0];
vc2.view.backgroundColor = [UIColor purpleColor];
vc2.view.frame = CGRectMake(0,500,50,50);
NSArray *tabs = [[NSArray alloc] initWithObjects:vc1, vc2, nil];
WIFCustomerDetailTabViewController *tvc = [[WIFCustomerDetailTabViewController alloc] init];
[tvc setViewControllers:tabs];
[self setDetailViewController:tvc];
Does anyone knows what can be happening here? I can't find the cause...
Images below..
Documentation for the UITabBarController class says, "you must install this view as the root of your window. Unlike other view controllers, a tab bar interface should never be installed as a child of another view controller".
It seems that you're attempting a design that's specifically not supported.

Resources