I have a view that I wish to present to the user in the standard way (sliding up from the bottom of the screen). About half this view is a transparent background and the bottom half has some input fields (imagine the way the keyboard pops up). When I call [self presentViewController] on the rootViewController, it slides the view up, but then about half a second later, where the view used to be transparent it is replaced with black instead. This happens with both presentViewController and presentModalViewController. How to change this behaviour?
This is possible, and rockybalboa provides a solution to this issue in the forum post on raywenderlich.com:
iOS 8 UIModalPresentationCurrentContext is not transparent?
That solution being, quoting balboa's answer, in Objective-C:
Before iOS 8, you do this:
[backgroundViewController setModalPresentationStyle:UIModalPresentationCurrentContext];
[backgroundViewController presentViewController:_myMoreAppsViewController animated:NO completion:nil];
in iOS 8, you have to do this:
backgroundViewController.providesPresentationContextTransitionStyle = YES;
backgroundController.definesPresentationContext = YES;
[overlayViewController setModalPresentationStyle:UIModalPresentationOverCurrentContext];
To supplement the above code with the Swift equivalent:
backgroundViewController.providesPresentationContextTransitionStyle = true
backgroundController.definesPresentationContext = true
overlayViewController.modalPresentationStyle = .OverCurrentContext
Having implemented this using Xcode 6.3 beta 3 on iOS 8.1 with Swift 1.2, it works perfectly.
Just a comment that I viewed three different SO questions on this - the more recent now marked as duplicates - prior to finding and attempting the Ray Wenderlich forum solution.
As far as I know, transparent background is not supported when you presents a model view controller. Try retain the controller in your root view controller and simply add subview to the root view controller.
In the end, it looks like it's not possible for it to be transparent, I've got around this by adding this view as a subview outside of the bounds of the root view controller, and then slid it into place using an animation block. Not a lot of extra code, but it would have been nice to be able to use standard iOS behaviour to do it.
I had a similar problem with the black background appearing after a short delay when creating the controller with
Disclaimer *vc = [[Disclaimer alloc]init];
What solved the problem for me was to create a corresponding object in IB and instantiate the viewcontroller using it's storyboard ID:
Disclaimer *vc = (Disclaimer *)[self.storyboard instantiateViewControllerWithIdentifier:#"SBIDDisclaimer"];
[self presentViewController:vc animated:YES completion:nil];
I guess doing it via IB does some additional initialisations.
Using SWIFT 4, just add this code to the view controller you want to have a transparent background.
override func viewDidLoad()
{
super.viewDidLoad()
self.modalPresentationStyle = .overFullScreen
self.view.backgroundColor = UIColor.clear
}
Related
This question already has answers here:
Transparent background for modally presented viewcontroller
(5 answers)
Closed 7 years ago.
I know this topic is quite popular, but I'm a little iniciate problem in a programming language, the fact is that I still do not understand where I put the code. Well, I'll tell the whole case:
I'm trying to make a modal Swift in a little different from normal: By clicking on a button, the ViewController is displayed (following modal type) on the screen, but with transparent background. Only the blue View with label will be displayed. When this ViewController is presented, it is with transparent background, but as soon as it completes the transition, it will stay with the black background. Already deactivated the opaque option, and tested some options, but nothing this troubleshooting.
Some can help me?
The video is a test in the simulator on the case (https://www.youtube.com/watch?v=wT8Uwmq9yqY).
I'm starting with swift, and I'm still pretty lost with how to program in Xcode, I read an answer to a question that has the following code to solve this:
self.presentingViewController.providesPresentationContextTransitionStyle = YES;
self.presentingViewController.definesPresentationContext = YES;
modal.modalPresentationStyle = UIModalPresentationOverCurrentContext;
Where do I put this code?
You can do it like this:
In your main view controller:
func showModal() {
let modalViewController = ModalViewController()
modalViewController.modalPresentationStyle = .overCurrentContext
presentViewController(modalViewController, animated: true, completion: nil)
}
In your modal view controller:
class ModalViewController: UIViewController {
override func viewDidLoad() {
view.backgroundColor = UIColor.clearColor()
view.opaque = false
}
}
If you are working with a storyboard:
Just add a Storyboard Segue with Kind set to Present Modally to your modal view controller and on this view controller set the following values:
Background = Clear Color
Drawing = Uncheck the Opaque checkbox
Presentation = Over Current Context
As Crashalot pointed out in his comment: Make sure the segue only uses Default for both Presentation and Transition. Using Current Context for Presentation makes the modal turn black instead of remaining transparent.
I am getting a really strange animation behaviour when pushing another view controller that has the bottom bar hidden with hidesBottomBarWhenPushed. The first thread I found was that: Strange animation on iOS 7 when using hidesBottomBarWhenPushed in app built targeting <= iOS 6 but as my application is only build and run on iOS7 it is not the case for my problem.
Please see the following video that shows the problem (look in the top right corner):
https://dl.dropboxusercontent.com/u/66066789/ios7.mov
This strange animation shadow only occurs when hidesBottomBarWhenPushed is true.
How can I fix that?
Solved my problem:
self.tabBarController.tabBar.hidden=YES;
In the second view controller is the way to go.
Leo Natan is correct. The reason for this blur effect is because the entire Tab Bar Controller is being animated underneath the navigation controller, and behind that view is a black UIWindow by default. I changed the UIWindow background color to white and that fixed the issue.
hidesBottomBarWhenPushed seems to work great with UITabBars (iOS 7/8).
Turn off the Translucent property of Navigation Bar in Storyboard.
In My Case, I had TabBarViewController with UINavigationController in each tabs & faced similar issue. I used,
nextScreen.hidesBottomBarWhenPushed = true
pushViewToCentralNavigationController(nextScreen)
It works fine when nextScreen is UITableViewController subclass & applied auto layout. But, It does not work fine when nextScreen is UIViewController. I found it depends on nextScreen auto layout constraints.
So I just updated my currentScreen with this code -
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
self.tabBarController?.tabBar.hidden = true
}
For more details - https://stackoverflow.com/a/39145355/2564720
An elegant way of doing this, while keeping transparency, is to add this to the root UIViewController:
- (void)viewWillAppear:(BOOL)animated {
[UIView animateWithDuration:0.35f animations:^{
self.tabBarController.tabBar.alpha = 1.0f;
}];
}
- (void)viewWillDisappear:(BOOL)animated {
[UIView animateWithDuration:0.35f animations:^{
self.tabBarController.tabBar.alpha = 0.0f;
}];
}
This way you'll get a nice fade-in/fade-out animation of the tab bar.
What if in the second view controller in viewWillAppear you put
[self.navigationController setToolbarHidden:YES animated:NO];
I am pushing a view controller via:
[self.navigationController pushViewController:[[UIViewController alloc] init] animated:YES];
But the animation lags/pauses a for half a second mid way through. The animation is not complete. Here's the gif;
With out more detail I can think of 2 possible problem with that.
Is there Shadow added in code to the view that will be covered by the new ViewController. If it is the case, use ShadowPath or an translucent view instead (the property Shadow is expensive while animating, been there done that)
Is the backgroundColor of new ViewController "clearColor" ? I've seen strange rendering problem with that kind of thing.
Try:
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [UIColor whiteColor];
[self.navigationController pushViewController:vc animated:YES];
That is the 2 possible problems I can think of the top of my head with so few detail.
Never rely on the default background color, it has change with iOS version and is not consistant across controls and can even be different if the view is created in code or from a Xib (in the same iOS version).
In app delegate, set your window's background color to white.
window?.backgroundColor = .white
Also in the the pushed view controller, set its view to white.
view.backgroundColor = .white
I experienced the same issue when programmatically embedding my view controller in a UINavigationController.
While setting the background color as suggested by VinceBurn solved the pausing, it made the entire animation white, fading in the actual content only when the animation finished.
For me the problem was solved by making sure the content was correctly sized in -viewDidLoad.
This question already has answers here:
Transparent Background with a Modal UIViewController
(6 answers)
Closed 9 years ago.
I am trying to display on the iPad a UIcontroller in my original viewcontorller, but smaller sized, so that the user is able to interact with it as well as with the contorller in the background. this was my aim but it is ok even if the user can't interact with the controller on the background, but it is essential to see the contorller in the background. I tried this code:
controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:controller animated:YES];
controller.view.layer.cornerRadius = 10; // this value vary as per your desire
controller.view.clipsToBounds = YES;
controller.view.frame = CGRectMake(343, 163, 316, 546.5);
This displays the controller with the set frame, but in the background you can't see the other controller, but just black. Why?
Definetely use this Presenting View Controllers from Other View Controllers and this About View Controllers
The section "Presentation Styles for Modal Views" says about your problem I think.
There are different presentation styles for controllers. You can set property - modalPresentationStyle to UIModalPresentationPageSheet or UIModalPresentationFormSheet that shows view controllers above other.
controller.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
controller.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentModalViewController:controller animated:YES];
Another way is using UIPopoverController. It designed for showing views that sized not all the screen view. But the touches on other view controller will hide it.
I have an UIViewController(called MainViewController) which presents modally a semi-transparent view (HelpOverlayViewController):
HelpOverlayViewController *helpOverlayViewController = [[HelpOverlayViewController alloc] init];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
helpOverlayViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentViewController:helpOverlayViewController animated:YES completion:nil];
If the user rotates the device while the HelpOverlayViewController is shown it only rotates HelpOverlayViewController and not the MainViewController i.e. the parent controller. This is a problem since HelpOverlayViewController is semi-transparent and MainViewController is visible below it.
Both controllers have the method
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
They both rotate fine independently.
Is there some way I can force the underlaying view controller to rotate when the modal view does?
I do know that issues like this will likely be largely resolved with iOS 6 as it has a different model for handling rotations.
However, that doesn't help you now. You might be best off just making your HelpOverlay a UIView and not a UIViewController. You can add this semi-transparent view onto the top of your MainViewController (or any other). You can still create an animation (like a fade-in) when adding this subview to your view hierarchy. With this model, you'll no longer have any issues with rotations.