UIPresentationController not calling containerViewWillLayoutSubviews until after display - ios

I have a UIPresentationController displaying a side menu over the main view with a fixed width of 300. Then from the side menu the user can open a full screen modal view. When the modal view is dismissed the menu view fills the screen during the dismissal animation (this is wrong). At the end of the animation containerViewWillLayoutSubviews is called and the menu corrects it's width to 300.
I do implement frameOfPresentedViewInContainerView. I am also implementing shouldPresentInFullscreen returning NO on the menu view (though this seems to not affect anything I can really determine).
Why isn't containerViewWillLayoutSubviews called before the dismssal animation? How should I be maintaining the menu view's width when it is covered and revealed?

Thanks to riadhluke for directing me to UIPresentationController changes size when another view controller is displayed on top of it
My solution is in my menu's prepareForSegue
UIViewController *destination = [segue destinationViewController];
if (destination.modalPresentationStyle == UIModalPresentationFullScreen) {
destination.modalPresentationStyle = UIModalPresentationOverFullScreen;
}
Which forces fullscreen modal presentations to be Over full screen, which causes the menu not to be lost, and therefore not re laid out post dismissal animation.

Related

Manually Trigger `automaticallyAdjustsScrollViewInsets` at a Certain Time

I have a UINavigationController, containing a UIViewController that is parent to two UITableViewController controllers.
When the user taps on a segmented control in the UIToolbar of the navigation controller, the current child table controller is swapped out with the new one. This includes removing the old controller from the parent hierarchy and removing its view as a subview of the parent view controller.
The first view controller that is displayed when the navigation view controller first presents it has its contentInset correctly configured by automaticallyAdjustsScrollViewInsets, however, when I pull that one out and insert the view from the second table view controller, that does not.
Furthermore, if I rotate the device (Which shrinks the UINavigationBar) and then swap back to the first view controller, its contentInset is now incorrect and it doesn't scroll properly. The second controller, however, does have its contentInset property properly set as a result of the device rotation.
Is there a way to manually force a UIViewController to redo its automaticallyAdjustsScrollViewInsets operation when I need it?
It's not an absolutely amazing one, but I found a solution that works.
Inserting a new child view controller isn't enough to trigger UINavigationController to automatically work out the appropriate contentInset values for any scroll views in the new child. BUT! You can force it to perform that calculation by doing something that would have required it anyway. For example, hiding and showing the navigation bar or toolbar.
- (void)insertViewController:(UIViewController *)viewController
{
// Add the view to our view
viewController.view.frame = self.view.bounds;
[self.view addSubview:viewController.view];
// Add the new controller as a child
[self addChildViewController:viewController];
[viewController didMoveToParentViewController:self];
// Show and hide the toolbar to force the content inset calculation
self.navigationController.toolbarHidden = YES;
self.navigationController.toolbarHidden = NO;
}
I've tested it, and there appear to be no visual glitches by rapidly hiding either the navigation bar or toolbar, so this solution seems to be acceptable.

pushViewController:animated: doesn't fully animate current controller out of bounds

I have a UINavigationController thats width is 255 and the rootViewController is a UITableViewController that is of the same width. The problem is that when I push a new view controller, the current rootViewController animates about 1/3 of the way off screen and then stays visible while the new controller comes in and then it disappears. If I set animated to NO it works fine, but I need to animate it. There isn't anything fancy going on in the code, it is a simple push/pop setup when switching controllers. I added a video below to show you what it looks like. I put borders on the navigation controller (blue) and table view (orange). The code that does the push/pop is:
if ([[self.menuNavigationController topViewController] isKindOfClass:[TeamMenuViewController class]])
{
[self.menuNavigationController pushViewController:self.teamsViewController animated:YES];
}
else
{
[self.menuNavigationController popToRootViewControllerAnimated:YES];
}
It looks like your viewController.view that is being pushed on has a transparent background. The default UINavigationController animation in iOS 7 and 8 has an overlap effect.

How to make a DejalActivityView over a popover view

I have a split view controller within a navigation controller and I want to put a DejalActivityView over everything it when I'm doing certain operations. Right now I'm using the following code:
- (void)showActivityView
{
UIView *viewToUse = [MSMasterViewController get].splitViewController.navigationController.view;
[DejalBezelActivityView activityViewForView:viewToUse];
[DejalActivityView currentActivityView].showNetworkActivityIndicator = YES;
}
This works in landscape mode, but when in portrait mode with the master view in popover form, the dejal activity view appears behind the popover. Is there a better view to use that will cover the whole screen?
Maybe you could use your Window as Superview, and only change relativ Frame positing.
greetings Oli

popover content view doesn't display while viewcontroller has a child VC present

I have a container view controller that consists of a navigation view at top, and a content view for the remainder of the screen. The navigation menu consists of several buttons, some of which present a popover with UITableView for secondary navigation. This all worked until I assigned a child view controller and set it's view as subview of the content view. Now, the popover appears, but has nothing inside it (no tableview, just black).
Why is this?
Here's the code I added for the child vc in container view:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
ContentWebViewController *initialVC = [[ContentWebViewController alloc] init];
[self addChildViewController:initialVC];
initialVC.view.frame = self.view.bounds;
[self.containerView addSubview:initialVC.view];
self.currentController = initial;
}
See the screenshot below. I added a vc with a simple webview showing google (just as a placeholder for now). The popover was working fine before I assigned the child VC.
Maybe it will help other in other cases -
If you are using size classes (probably you are since you are developing this to iPad) -
Design your popover view controller in Any-Any size and it should be OK - after that you can return to your wanted size.
(You can also uninstall the size classes of any object in that view controller instead of redesign the VC)
I somehow (don't ask me how) changed the class that my table view controller was inheriting from. It should have been (obviously) UITableViewController, but was UITableViewController, so initWithStyle was not being called....

With UIPresentationFormSheet, why doesn't my view move above the keyboard when it is up?

Apple says:
UIModalPresentationFormSheet
The width and height of the presented view are smaller than those of the screen and the view is centered on the screen. If the device is in a landscape orientation and the keyboard is visible, the position of the view is adjusted upward so that the view remains visible. All uncovered areas are dimmed to prevent the user from interacting with them.
But my view doesn't move up when the keyboard is visible. I basically want to present a textview modally above the keyboard so the user can enter text and then hit send (in a nav bar button on the presented view.)
My presenting view is a UISplitViewController (not one of its children) and I'm presenting UINavigationController who's top view controller is basically a UITextView. Rotation works, but the presented view is overlapped by the keyboard in both orientations.
I found some questions asking how to resize the presented view in this case, which is nice, but I don't want to have to make assumptions by resizing manually in the presenter or in the presented view. It seems like it should just pick a decent (undocumented) size just move it up automatically when the keyboard shows.
My presenting code looks like this:
MyViewController *vc = [[MyViewController alloc] init];
UINavigationController *nav = [[[UINavigationController alloc] initWithRootViewController:vc] autorelease];
nav.modalPresentationStyle = UIModalPresentationFormSheet;
[self.splitViewController presentModalViewController:nav animated:YES];
As I was finishing up my question, I realized I was calling becomeFirstResponder on my UITextView in viewWillAppear. If you change it to viewDidAppear it will work, which makes sense.

Resources