Why Does presentModalViewController:animated: Turn The Background Black? - ios

I am using presentModalViewController:animated: and while functionally it works correctly visually it has an artifact I want to remove. When the modally presented viewController appears its parent viewController is completely hidden with the background turning black. This is not what I want. My child viewController's view is translucent and I want to reveal the parent viewControllers view behind it. The effect I want is a piece of tracing paper sliding over the background.
I assumed presentModalViewController:animated: supported this. Is that not the case?
Thanks,
Doug

NavigationController and the View Controllers are designed in such a way that only one view controller may show at a time. When a new view controller is pushed/presented the previous view controller will be hidden by the system. So when you reduce the modal view's alpha you will possibly see the window's backgroundColor (the black color you see now).
If you want a translucent view to slide-in over the main view, you can add the view as the subView of main view and animate it using UIView Animations.

This may get you what you want:
presentingViewController.modalPresentationStyle = UIModalPresentationCurrentContext;

presentingViewController.modalPresentationStyle = UIModalPresentationCurrentContext;
doesn't work after ios7,you can fix it by after
presentingViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
presentingViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
then both:
[appViews.rootViewController presentViewController:presentingViewController animated:YES completion:nil];

Related

Using Modal View Controllers and UIVisualEffectView

I'm trying to solve the problem described in this blog post: http://justabeech.com/2014/10/22/using-uivisualeffectview-in-a-modal-view-controller/
I have a UIViewController with a storyboard modal segue to another UIViewController of which the UIView has a background colour of [UIColor clearColor]and a UIVisualEffectView.
When I present the view controller, the visual effect is blurred until the transition is completed and then the background turns grey again (exactly as displayed in the gif on that blog post).
I set the Modal Transition Style to FullScreen as specified, but still the same problem remains. What else could I be missing to make this work?
EDIT: Also, I get the following error:
Warning: Attempt to present <ClocksDetailViewController: 0x7ff89cb5bc70> on <ClocksViewController: 0x7ff89c8afe90> whose view is not in the window hierarchy!
Thanks
You have probably used UIModalPresentationFullScreen instead of the correct UIModalPresentationOverFullScreen.
With the old UIModalPresentationFullScreen all the views under the presented controller are removed from the view hierarchy once the animation ends.
You need to set the modal presentation style of the UINavigationController, instead of the the UIViewController.
UINavigationController* navigationController = [[UIStoryboard storyboardWithName:#"myStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"myViewController"];
navigationController.modalPresentationStyle = UIModalPresentationOverFullScreen;

ModalViewController Translucent Background

I was using that piece of code to display a UIViewController as a modal with a translucent background (Working on IOS7 and lower).
MyViewController *myViewController = [[MyViewController alloc] init];
navController.modalPresentationStyle = UIModalPresentationCurrentContext;
[navController presentViewController:myViewController animated:NO completion:nil];
Now compiling with IOS8 show a modal with a black background.
Is there any solution ? (Without make an animated subView)
Thanks.
In iOS 8 and above, you can use 'UIModalPresentationOverCurrentContext' for this purpose. From the UIViewController documentation:
UIModalPresentationOverCurrentContext
A presentation style where the content is displayed over only the
parent view controller’s content. The views beneath the presented
content are not removed from the view hierarchy when the presentation
finishes. So if the presented view controller does not fill the screen
with opaque content, the underlying content shows through.
When presenting a view controller in a popover, this presentation
style is supported only if the transition style is
UIModalTransitionStyleCoverVertical. Attempting to use a different
transition style triggers an exception. However, you may use other
transition styles (except the partial curl transition) if the parent
view controller is not in a popover.
Available in iOS 8.0 and later.
I was not aware that see-through modally presented view controllers were ever supported prior to iOS 8 (and will be looking into that for my own use), but the above option definitely works in my testing in the new OS.
Note: Be sure to give your presented view controller a backgroundColor of clearColor.

REALLY strange app color behavior?

On appDidFinishLaunchingWithOptions, I tint my entire app red with the following code.
self.window.tintColor = [UIColor otfRedColor];
This works perfectly, and when my app loads, all the navigation bar items are red. A is my root view controller.
I have 3 view controllers, a, b, and c. A pulls up a modal presentation view sheet of b which pulls up a full modal view of c. When C is pulled up, the bar button items on navigation bar are all tinted gray, this shouldn't be happening because I didn't alter any tint or color in any way after the app delegate tinted the window. I then use
[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];
to dismiss VC c and b, but now my ENTIRE app is tinted gray. I haven't used any tint code at all since the app delegate, why does this happen? When I go from A to B again, that navigation bar items are still red???
Code to pull up view controller B from A:
AthleteAdd *addAthlete = [self.storyboard instantiateViewControllerWithIdentifier:#"addAthlete"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:addAthlete];
addAthlete.delegate = self;
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navigationController animated:YES completion:nil];
Code to pull up C from B:
MedicalReleaseVC *medRelease = [self.storyboard instantiateViewControllerWithIdentifier:#"showMedRel"];
medRelease.delegate = self;
[self presentViewController:medRelease animated:YES completion:nil];
Does anyone know why this happens, or have an idea? I have tried tinting the third view controller as red 3 separate ways and it still remained gray, then when everything is dismissed my entire app is gray. Please help!!
EDIT:
If it helps, the way I solved this problem was by setting the following in my appdelegate.m
self.window.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
I think this is a bug in iOS7's handling of tintAdjustmentMode when opening and closing sheets and popovers. I've seen this bug happen in Apple's native mail app, where the bar button items become gray, or conversely, they no longer turn to gray once a popover shows up.
To debug this further, I suggest subclassing one of your views (or the window directly) and implementing tintColorDidChange. Log the value of tintAdjustmentMode there. I fear this is what is causing your gray tint issues.
One solution would be to force UIViewTintAdjustmentModeNormal but this would have the effect of no dimming when opening a popover or a sheet.
I had to put
[[[UIApplication sharedApplication] keyWindow] setTintAdjustmentMode:UIViewTintAdjustmentModeNormal];
in my viewDidLoad to solve this issue. But as mentioned in other answers, it does have the adverse effect of not dimming the bar button items when a popup is up.
I set this at the appearance proxy level.
UINavigationBar.appearance().tintAdjustmentMode = .normal
Just put
self.view.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
in your viewDidLoad and your colors are back to normal.
There is definitely a bug. I noticed that when the popover does dim the window when it appears but after I change the keyWindow.tintAdjustmentMode manually (for custom views & modal view controllers), the popover will stop dimming even though I set the keyWindow.tintAdjustmentMode back to automatic.
When a popover is shown, the main view's TintAdjustmentMode is set to Dimmed. This should be reversed when the popover is closed, but when you navigate to a new screen from the popover, it doesn't happen for some reason.
I fixed this in the UIViewController being displayed as the popover - override the ViewWillDisappear method and set the TintAdjustmentMode on the main view controller's view back to Normal. (In Xamarin, I used UIApplication.SharedApplication.KeyWindow.RootViewController.View.TintAdjustmentMode = UIViewTintAdjustmentMode.Normal with a few checks for nulls along the way.)
Another solution is to NOT set the window tintColor and instead use appearance proxies where appropriate and set tintColor programmatically (or in Interface Builder) everywhere else. This appears to be safer than setting the global window tintColor, which elicits strange behavior especially after modals, system alerts, and action sheets dismiss.
Remove this:
self.window?.tintColor = UIColor.redColor()
Add these:
UINavigationBar.appearance().barTintColor = UIColor.redColor()
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
UISegmentedControl.appearance().tintColor = UIColor.orangeColor()

iOS adding a view of view controller but it's Not fully flushed to top

I added a view of view controller by using
[self.view addsubview view controller.view];
but as the picture indicates, it's fully flushed to the top.
the underneath view controller has a navigation bar.
You also need to position the new view controller's view by specifying its frame. Otherwise it will do something you don't expect, like now.
Depending on what you want, it could be:
controller.view.frame = self.view.bounds;
This will just overlap the current VC's view with the new VC's view.
Or change it as necessary depending on what you need.
Like BlackRider said, a best approach is to assign the superview's bounds to the frame of the added view:
[self.view addSubview: viewcontroller.view];
viewcontroller.view.frame = self.view.bounds;
This is the perfect way to set the size and position for a newly-added subview, to perfectly overlap a parent view.
Adding another UIViewController's view is most often not the best way. However, I have found this technique may be the most effective way, if not the only way, to achieve some special animation transitions. This, followed by removing the added view and presenting the new UIViewController with no animation.
If no special animation or view hierarchy arrangement is necessary, it's probably not a good idea. If you want the new view controller to be full-screen, use:
[self presentViewController: viewcontroller animated:YES completion:nil];
otherwise if you want it to be part of the navigation controller, push it onto the navigation controller's stack. In your example, assuming self is the current top controller:
[self.navigationController pushViewController:viewcontroller animated:YES];
For more info, check out Presenting a View Controller and Choosing a Transition Style:
http://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html#//apple_ref/doc/uid/TP40007457-CH111-SW3

Hide bottom bar on demand

I have a UINavigationController inside a UITabBarController. I'm presenting a sort of popover view using a semi-transparent UIView, but am not calling presentModalViewController or any of the usual methods. I know about hidesBottomBarWhenPushed, but is there a way I can hide the bottom bar (or even betterm slide it out) on demand (just before my subView is added to the navigationController's top view)?
Have you tried setting this property?
navigationController.toolbarHidden = YES;
Or with animation:
[navigationController setToolbarHidden:YES animated:YES];
See answer https://stackoverflow.com/a/9141766/305351 to related question.
Specifically Borut Tomazin's comment and his solution https://gist.github.com/borut-t/6507423.

Resources