Swift Modal View Controller with transparent background [duplicate] - ios

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.

Related

Why viewDidLoad function is not called?

I want to change UIBarButton's color in the navigationBar. To achieve this, in viewDidLoad: I put this line:
navigationController?.navigationBar.tintColor = .white
Everything works fine until I started to notice something strange. That UIBarButton is used to dismiss the UIViewController. When it is pressed, I just dismiss the viewController. But, if I present it (viewController) again, the color of the UIBarButton is not white, it gets tintColor of the application.
After doing some debugging, I noticed that viewDidLoad: is not called again after the viewController is just dismissed and presented again. The reason why my UIBarButton has a different color is because I change its color in viewDidLoad:. When viewDidLoad: is not called, of course, color is not changed.
It was an interesting discovery for me the fact that iOS doesn't call viewDidLoad: for UIViewController that was presented already. Possibly, it is due to the optimisation, because it is not efficient to draw the whole UI every time.
My solution to this problem can be to change color, not in viewDidLoad:, but in viewDidAppear:. But, is it right approach to solve a problem? And why viewDidLoad: is not called in the above situation?
It looks like you create and store you view controller, but present it wrapped in UINavigationController:
let controller = YourModalViewController()
...
func presentMyModal() {
present(UINavigationController(rootViewController: controller))
}
In this case your viewDidLoad method will be called just once and you'll have visual bug. If you want to leave styling code of your modal inside it's file you can create instance func which will return this controller wrapped and styled.
extension YourModalViewController {
func wrappedInNC() -> UINavigationController {
let nc = UINavigationController(rootViewController: controller)
// Styling code.
return nc
}
}

How is this settings popup created? [duplicate]

This question already has answers here:
Present a popover from an arbitrary anchor point in Swift
(3 answers)
Closed 4 years ago.
I really like the way the settings are shown on the Books app and am trying to figure out how replicated it.
Screenshot of Books app with settings shown
Is this an .actionsheet that is somehow moved to show up under the Settings image or a container view that shows up on tap or something else? I'm still at level noob with a basic app and would like to implement this.
It is iOS default presentation style for controllers. It's called UIPopOverPresentationController. Here's a good article on presentation controllers. After that you might want to create two to three cells for your options in a UITableView and add that as controller for the popover from your storyboard.
You can also change the popover arrow pointing location and direction which you might need when you want to support your app for iPad as well. :)
#IBAction func actionWasTapped(sender: UIBarButtonItem) {
let storyboard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "PopOverVC")
vc.modalPresentationStyle = .popover
let popover: UIPopoverPresentationController = vc.popoverPresentationController!
popover.barButtonItem = sender
present(vc, animated: true, completion: nil)
}
This can done with a-lot of way , you can just create by
UIView work as background with custom subview (PopOverMenu) done with UIBezierPath to draw this arrow with corner radius view
upon this pop over you can create MultiSection tableview or collection View or any
Background is add as SubView to UIApplication.sharedApplication().keyWindow?.addSubview(background)
Background have tab gesture to dismiss when tab on background
some closure to bring back data that user select it

Why is my navigation item/bar very dark in colour?

I am building a help screen view controller of my app. It basically contains a UIWebView because I want to use HTML to display the help text. There is also another view controller which is kind of the "main" VC. There is a "Present as Popover" segue connecting the two.
From the IB, I see this:
I have an unwind segue that unwinds to the main VC. It will be triggered if the user taps the "Done" button.
And here is my code:
import UIKit
class HelpViewController: UIViewController {
#IBOutlet var webView: UIWebView!
override func viewDidLoad() {
automaticallyAdjustsScrollViewInsets = false
let htmlString = "You don't need to know about this."
webView.loadHTMLString(htmlString, baseURL: nil)
}
#IBAction func doneClicked(sender: UIBarButtonItem) {
performSegueWithIdentifier("exitToMain", sender: self)
}
}
And the unwind segues are working perfectly but the navigation bar is somehow very dark in colour!
I don't know what's happening here. I checked out this question
iOS 7 SDK - UI Navigation Bar is sometimes darker and sometimes not. But why?
The asker said that's because of a piece of code that he wrote but I swear I didn't use the same code as he did (from my limited obj-c to swift translation knowledge)!
Anyway, here is the relevant storyboard hierarchy thingy:
What causes this problem and how to fix it?
I solved the problem by setting the background colour of the UIWebView to white. And the navigation bar turns white!
I found this by observing how the colour changes when I scroll the web view up and down. I saw that initially it is kinda grey. But when I scrolled down to the white part of the web view, it changes to white. I deduced that the grey colour is actually the web view's background property and the navigation bar is kind of translucent.
And that's why setting the background colour to white fixes this issue.
Stretch the web view through the bottom of the navigation bar and set automaticallyAdjustScrollviewInsets to true. That would adjust the scroll view inset to show the content at the right content.
did you try this
self.navigationController!.navigationBar.translucent = true

UITransitionView on top of ViewController using UIModalPresentationStyle.OverCurrentContext [duplicate]

This question already has an answer here:
Pass touches through a UIViewController
(1 answer)
Closed 7 days ago.
I'm trying to set a view controller on top of another while keeping some of the first on visible.
However, I can't see the first one because I have a UITransitionView with a UIView on top of it (the first one is in the hierarchy and that's how I know .OverCurrentContext is working)
This should be a very simple code and I'm not sure what's going on. I know I can't touch the UITransitionView and that's why I'm not sure what to do.
let vc = storyBoard.instantiateInitialViewController() as MyPresenterViewController
vc.view.backgroundColor = .clearColor()
vc.modalPresentationStyle = .OverCurrentContext
viewControllerToPresentIn.presentViewController(vc, animated: true, completion: nil)
Suggestions would be highly appreciated.
Best regards,
A little late to the party with this response, but I recently had at a similar problem. A modal I wanted to present (with a semi-transparent veil) was being contained by a white UITransitionView, hiding the underlying views. I suspect this TransitionView gets injected when you issue a controller.present() call to show your Modal in some circumstances (but don't know why or when)
As a quick and dirty workaround, you can try to clear the background of the parent views of your modal before you present. For some reason, the UITransitionView then also gets a clear colour once you present your modal.
extension UIView {
//This will eventually get to the UITransitionView and clear the background.
func clearHierarchyBackground() {
self.backgroundColor = .clear
if let superView = self.superview {
superview.clearHierarchyBackground()
}
}
}
let parentController = MyParentViewController()
let childController = MyModalViewController()
childController.modalPresentationStyle = .overFullScreen //.overCurrentContext should also work..
childController.view.clearHierarchyBackground()
/* The above makes your controller root view .clear
so you need to add subviews with transparency &
content as you see fit.*/
parentController.present(childController, animated:true....)

presentViewController black background instead of transparent

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
}

Resources