There are many q/a's on this topic, many of them referring to older versions of iOS. The best answer I could find on the subject was this one.
It almost works for me, but when presenting this over a UITabBarViewController subclass, it only partially works: I get a nice, semi-transparent view during the presentation animation, but once the presentation animation completes, the presented VC becomes opaque again.
Coded in Objective-C, but I'm happy to read Swift answers...
- (void)showBusyWithCompletion:(void (^)(BOOL))completion {
UIViewController *vc = [[UIViewController alloc] init];
vc.view.backgroundColor = [[UIColor redColor] colorWithAlphaComponent:0.5];
vc.view.opaque = NO;
vc.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:vc animated:YES completion:^{
[self performSelector:#selector(hideBusy:) withObject:vc afterDelay:4];
}];
}
- (void)hideBusy:(UIViewController *)vc {
[self dismissViewControllerAnimated:vc completion:nil];
}
Again, the presenting VC is a UITabBarVC subclass, with nothing done to it except some code to record which tabs were visited. The presented vc is a vanilla view controller. Its view appears transparent red as it slides over, then turns opaque red (darker, like it's being blended with black) once the transition is complete.
How can I keep the background transparent after it appears?
It turns out that the answer I refer to above is correct, and I transcribed the setting improperly. To recap: this doesn't work (and the other answer didn't claim it did):
vc.modalPresentationStyle = UIModalPresentationCurrentContext;
...but either of these do:
vc.modalPresentationStyle = UIModalPresentationOverFullScreen;
or as #TylerTheCompiler points out:
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
Related
I am trying to push a view controller with transparency mode.
This is my code:
SearchViewController * searchViewController= [self.storyboard instantiateViewControllerWithIdentifier:#"SearchViewController"];
searchViewController.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7f];
[self.navigationController pushViewController:searchViewController animated:YES];
Something i did mistake find out and help me to solve this problem.
In iOS the default color of background is black.
So you navigation controller has a black background.
If you push a controller, you current controller will be replaced by your new one. If the new one have a transparent color you will see the view of your navigation.
If I understand you want your first controller to be still visible ?
If yes, then you should use :
SearchViewController * searchViewController= [self.storyboard instantiateViewControllerWithIdentifier:#"SearchViewController"];
searchViewController.view.backgroundColor = [UIColor colorWithWhite:0 alpha:0.7f];
[self presentViewController:searchViewController animated:YES completion:nil];
You can also use a custom segue to have the cor
You have to set modalPresentationStyle with overFullScreen value
let viewController = SearchViewController(nibName: "SearchViewController", bundle: nil)
viewController.modalPresentationStyle = .overFullScreen
present(viewController, animated: false, completion: nil)
I try to open a popup with a transparent background so that we can see the screen behind the popup.
I use this code :
- (void)presentErrorMessageVC:(NSString *)message {
// Get error message vc
S6ErrorMessageVC *vc = [[S6ErrorMessageVC alloc] initWithNibName:#"S6ErrorMessageVC" bundle:nil message:message];
if (vc) {
// Set delegate
vc.delegate = self;
// Present error message vc
[self presentViewController:vc animated:NO completion:nil];
}
}
Which works perfectly, except for ipad 4, where the background is black. I've also tried to add
vc.view.backgroundColor = [UIColor clearColor];
But still the background is black...
Any idea?
Thx
This may help you solve your problem.
vc.modalPresentationStyle = UIModalPresentationCurrentContext;
I'm attempting to present a VC modally that shows a blur of the previous view controller. This is my attempt. The problem is that this only works maybe 50% of the time. Half of the time the blur works as intended, the other half I only get the grey blur as if the background is black (no background content).
-(void)plusButtonPressedOnCell:(SASearchTableViewCell *)cell
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"ActionMenu" bundle:nil];
SAActionMenuViewController *actionMenuVC = (SAActionMenuViewController *)[storyboard instantiateInitialViewController];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:actionMenuVC animated:NO completion:^{
//animations
}];
}
Any ideas why this is happening?
My presentation style was incorrect, and I was attempting it on the wrong view controller. This was the fix.
This line:
self.modalPresentationStyle = UIModalPresentationCurrentContext;
needed to be:
actionMenuVC.modalPresentationStyle = UIModalPresentationOverFullScreen;
That simple example but that don't work;
I have ViewController where inside on NavigationConroller, then I want to add new ViewConroller with its self navigation controller.
In main viewController:
CustomViewController *vc = [[CustomViewController alloc] init];
NewNavigationVC *nav = [[NewNavigationVC alloc] initWithRootViewController:vc];
[self presentViewController:nav animated:NO completion:nil];
Two controllers has a background color clear, but still black color.
Navigation bar I can do clear, but not a view.
UPDATE:
if i change self.window.backroundColor to red for example, that work but not clear
UPDATE 2:
[self addChildViewController:vc];
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];
and when I want to dealloc vc
[vc willMoveToParentViewController:nil];
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
All work ok without navigation controller
A viewController's view's backgroundColor can't be clear (as in showing the previous viewController's view on the stack). Pushing or presenting a viewController will put the new viewController on the stack and hide the previous viewController completely.
If you want a clear backgroundColor on the view, you will need to either:
1) set the viewController as a childViewController of the previous viewController - then animate the transition yourself.
Or
2) transplant the viewController logic into the previous viewController and have a new uiview act as that view (you also need to animated the transition yourself).
The solution is as follows. For clear example we use tableViewController:
UITableViewController *modalVC = [UITableViewController new];
UINavigationController *modalNVC = [[UINavigationController alloc] initWithRootViewController:modalVC];
UIViewController *mainVC = [UIViewController new];
UINavigationController *mainNVC = [[UINavigationController alloc] initWithRootViewController:mainVC];
modalVC.view.backgroundColor = UIColor.clearColor;
mainVC.view.backgroundColor = UIColor.redColor;
mainNVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[mainNVC presentViewController:modalNVC animated:YES completion:NULL];
The key feature is that you have to set modalPresentationStyle of presentingViewController to UIModalPresentationCurrentContext.
It works fine BUT without slide animation. You will get result immediately.
But you can still use "blood hack" to retain visual animation by successive presenting, dismissing and presenting again:
modalVC.view.backgroundColor = UIColor.clearColor;
mainVC.view.backgroundColor = UIColor.redColor;
[mainNVC presentViewController:modalNVC animated:YES completion:^{
[modalNVC dismissViewControllerAnimated:NO completion:^{
mainNVC.modalPresentationStyle = UIModalPresentationCurrentContext;
[mainNVC presentViewController:modalNVC animated:NO completion:NULL];
}];
}];
You basically need to tell the navigation controller to:
navigation.modalPresentationStyle = .overCurrentContext
In other words:
A presentation style where the content is displayed over another view controller’s content.
and that's it.
You can also make sure that:
navigation.view.backgroundColor = .clear
I am creating a viewcontroller in this way:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"PhotoViewControlleriPhone" bundle:nil];
UIViewController *vc = [sb instantiateInitialViewController];
vc.view.backgroundColor = [UIColor clearColor];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:vc animated:NO];
vc.view.frame = CGRectMake(imageView.frame.origin.x, imageView.frame.origin.y + 64, imageView.frame.size.width, 200.000000);
vc.view.layer.cornerRadius = 10; // this value vary as per your desire
vc.view.clipsToBounds = YES;
The viewcontroller is not full screen, so you can still see the previous one. I want to be able to see it, but lock it. Just like when you use ios facebook sharing, you see the background, but it becomes darker and you can't interact with it. How can I do this?
I believe the problem is that you’re displaying it using -presentModalViewController:animated:. Using that method carries with it some assumptions about the view controller you’re hosting; one of the assumptions it makes (on iPhone-type devices, at least) is that the view controller takes up the entire screen and is opaque.
To get around this, try adding the modal view controller’s view to the current view controller’s view manually. You’ll need to set the view controller hierarchy up to match the view hierarchy, so your code would look like this:
[self addChildViewController:vc];
[self.view addSubview:vc.view];
You’ll need to adjust the incoming view’s frame to position it within its new superview, but that should allow you more freedom.
My workaround is to take a screenshot with code, pass the UIImage as a parameter to the new UIViewController, and display it as a background image. In that way it appears transparent, and the you don't have to disable the underlying controls that might be reachable/accessible.
iOS8+
You can use below code snippet for iOS8+, its worked for me
SecondViewController *secondViewController = [[SecondViewController alloc] init];
secondViewController.modalPresentationStyle = UIModalPresentationOverCurrentContext;
[self presentViewController:secondViewController animated:YES completion:nil];