I am trying to present a custom view from a controller modally, however when I do so the background of everything but the textfield I have turns black as seen in here . (the intended modal)
This seems to be a fairly common problem, however I have already implemented the code that most similar questions pose as the answer
here is my addEvent method in the first controller:
#IBAction func addEvent(_ sender: Any) {
let newEventViewController = NewEventViewController()
newEventViewController.view.backgroundColor = UIColor.clear
newEventViewController.view.isOpaque = false
navigationController?.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
navigationController?.present(newEventViewController, animated: true, completion: nil)
}
Any help figuring out what I am missing would be appreciated. If it makes a difference I am creating my app using individual xib files and not a storyboard.
You need to set the modalPresentationStyle of newEventController not the navigationController like this:
newEventViewController.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
Also although not needed I would present from self rather than the navigation controller like this:
self.present(newEventViewController, animated: true, completion: nil)
Related
In Start Developing iOS Apps (Swift): Implement Edit and Delete Behavior
, The offical tutorial tell me should use presentingViewController and navigationController to indicate the specified view is Edit or Show, Like following code:
#IBAction func cancel(_ sender: UIBarButtonItem) {
// Depending on style of presentation (modal or push presentation), this view controller needs to be dismissed in two different ways.
let isPresentingInAddMealMode = presentingViewController is UINavigationController
if isPresentingInAddMealMode {
dismiss(animated: true, completion: nil)
}
else if let owningNavigationController = navigationController{
owningNavigationController.popViewController(animated: true)
}
else {
fatalError("The MealViewController is not inside a navigation controller.")
}
}
The adding view is presented by modal, the editing view is presented by embed navigation controller, But I think this approach is not good to understand and easy maintain, How about introduce a isEditOrShow instance varible in the view to indicate the state? like following:
#IBAction func cancel(_ sender: UIBarButtonItem) {
// Depending on style of presentation (modal or push presentation), this view controller needs to be dismissed in two different ways.
if isEditingOrShow = .edit{
dismiss(animated: true, completion: nil)
}
else isEditingOrShow = .show{
owningNavigationController.popViewController(animated: true)
}
}
The tutorial explains that, there are two ways in which you can dismiss view controllers.
For example, when you present a view controller as modal, you can use the below code to dismiss it.
dismiss(animated: true, completion: nil)
However, if you are using a push presentation (Navigation controller), then you should use the below code to dismiss it.
owningNavigationController.popViewController(animated: true)
How about introduce a bool isEditOrShow instance varible in the view to indicate the state?
From what I understand, you won't be needing isEditOrShow variable. If you have any questions, let me know.
I would like to show a popup (I just have UIAlertController in mind) like the the image below:
What I want to achieve
I found some kind of similar questions on the internet but they are code based, this way it is really hard to align the stuff in the position I want and handle the user interaction.
Is there a way that I kinda make a separate "Something" in the Storyboard and then here just pop that up? I thought of a whole ViewController but that covers the whole screen.
Any suggestions or solutions are highly appreciated. 🙏
You need to present it modally , so make the VC give it identifier and load it anywhere
let vc = self.storyboard?.instantiateViewController(withIdentifier: "popupID") as! PopupViewController
vc.sendedStr = "someContent"
vc.myImage = UIImage(named:"flag.png")
vc.providesPresentationContextTransitionStyle = true;
vc.definesPresentationContext = true;
vc.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
self.present(vc, animated:true, completion: nil)
//
class PopupViewController : UIViewController {
var sendedStr:String?
var myImage:UIImage?
}
More importantly is to set background of the view in IB like this
ViewController Doesn't fill the entire screen all the time. This is just the default setting.
Set .modalPresentationStyle property of your child controller to .overCurrentContext and present it modally.
Now, if you view Controller has an transparent background, it will be presented like an alert.
First design viewController in storyBoard and keep in mind your ViewController main view background color should be either clear or change its Alpha to like 0.5
Add below extension
extension UIViewController {
open func presentPOPUP(_ viewControllerToPresent: UIViewController, animated flag: Bool, modalTransitionStyle:UIModalTransitionStyle = .coverVertical, completion: (() -> Swift.Void)? = nil) {
viewControllerToPresent.modalPresentationStyle = .overCurrentContext
viewControllerToPresent.modalTransitionStyle = modalTransitionStyle
self.present(viewControllerToPresent, animated: flag, completion: completion)
}
}
After that you can use it like below
if let alerVC = self.myStoryBoard.instantiateViewController(withIdentifier: "AlertMessageVC") as? AlertMessageVC {
self.presentPOPUP(alerVC, animated: true, modalTransitionStyle: .crossDissolve, completion: nil)
}
you can also change modalTransitionStyle to below options
.coverVertical
.flipHorizontal
.crossDissolve
.partialCurl
Hope this help. :)
In my App, I've created a new storyboard that serves as a very basic tutorial for how to use certain features. (Instructions.storyboard). This storyboard has it's own class - InstructionsVC.swift
I want to present InstructionsVC when MainVC loads within viewDidAppear.
It works great. Fires up on App load just like it's supposed to. The problem occurs when I press the [Close] button on the Instructions interface. It closes the VC, fades to the main screen, and then immediately fires the Instructions VC back up.
How can I prevent the Instructions VC from loading back up once it's closed?
func openInstructions() {
let storyboard = UIStoryboard(name: "Instructions", bundle: nil)
let instructionsView = storyboard.instantiateViewController(withIdentifier: "instructionsStoryboardID")
instructionsView.modalPresentationStyle = .fullScreen
instructionsView.modalTransitionStyle = .crossDissolve
self.present(instructionsView, animated: true, completion:nil)
}
override func viewDidAppear(_ animated: Bool) {
openInstructions()
}
And within my instructions class, I have the following action on the close button:
#IBAction func closeButtonPressed(_ sender: UIButton) {
let presentingViewController: UIViewController! = self.presentingViewController
presentingViewController.dismiss(animated: true, completion: nil)
}
Note - I'd rather not use UserDefaults to resolve this, because I'm going to be incorporating something similar in other parts of the App and don't want to resort to UserDefaults to achieve the desirable behavior.
Thanks in advance buddies!
viewWillAppear and viewDidAppear are called every time a view controller's content view becomes visible. That includes the first time it's rendered and when it's shown again after being covered by a modal or by another view controller being pushed on top of it in a navigation stack.
viewDidLoad is only called once when a view controller's content view has been loaded, but before it is displayed. Thus when viewDidLoad is called it may be too soon to invoke your second view controller.
You might want to add an instance variable hasBeenDisplayed to your view controller. In viewDidAppear, check hasBeenDisplayed. If it's false, display your second view controller and set hasBeenDisplayed to true.
Looking at Apples Resource for using showViewController() versus presentViewController() I can't seem to figure out my issue here.
I want to display a viewController from my storyboard programmatically by doing the following:
if let resultController = storyboard!.instantiateViewControllerWithIdentifier("mainTab") as? TabBarController {
showViewController(resultController, sender: UIBarButtonItem.self)
}
This works fine. However, it's presentation is always modal. Covering the screen vertically from bottom to top like so:
I was/still am under the impression that I should use showViewController to display a screen without the animation... But clearly I'm missing something here. All I want to do is display the VC non-modally. I feel like I've tried everything to no avail.
Thanks for the advice in advance.
I think you want to use something like this.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("Controller") as! UIViewController
self.presentViewController(vc, animated: false, completion: nil) // no animation or presentation as modal because animated is false
The key is to have animated set to false. This method works for me. Hope this helps!
I want to switch to a new view controller when I press a button without using a navigation controller and I can't seem to be able to do this. I have looked everywhere for an answer but everything that I have found is either in objective-c, using a navigation controller, or not working at all.
func gunsoutButtonPressed(sender:UIButton!) {
print("yay\t")
//let encounterVC:AnyObject! = self.storyboard?.instantiateViewControllerWithIdentifier("ecounterViewController")
//self.showViewController(encounterVC as UIViewController, sender: encounterVC)
let encounterViewController = self.storyboard.instantiateViewControllerWithIdentifier("encounterViewController") as encounterViewController
self.pushViewController(encounterViewController, animated: true)
}
You have to connect the two ViewControllers you would like to use. Then name the segue however you want and then use the following code to trigger the segue (inside an IBAction or something). It is not completely programmatically but you can trigger them programmatically, which should be enough.
performSegueWithIdentifier("mySegue", sender: nil)
Check out this video for support.
Hope this helps :)
You cannot use a push segue without a UINavigationController. You could achieve this with a modal segue, such as this:
self.presentViewController(encounterViewController, animated: true, completion: nil)
Segue
So you use the Segue ID to make sure you segue correctly.
No Segue
I would suggest doing this instead though:
let vc = ViewControllerToSegueTo()
self.presentViewController(vc, animated: true, completion: nil)
It is slightly better if you do not want to use the storyboard.