Navigation bar does not appear after login button pressed when it moves to Home view controller and I have setup my storyboard and put all thing well but I think i am stuck at this point in code.
Actually there is no segue but coding instead so How I do navigation working?
Code I used to perform Navigation
let vc = self.storyboard?.instantiateViewController(withIdentifier: "Home")
self.present(vc!, animated: true, completion: nil)
#IBAction func loginAction(_ sender: Any) {
if self.emailTextField.text == "" || self.passwordTextField.text == "" {
//Alert to tell the user that there was an error because they didn't fill anything in the textfields because they didn't fill anything in
let alertController = UIAlertController(title: "Error", message: "Please enter an email and password.", preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
} else {
FIRAuth.auth()?.signIn(withEmail: self.emailTextField.text!, password: self.passwordTextField.text!) { (user, error) in
if error == nil {
//Print into the console if successfully logged in
print("You have successfully logged in")
//Go to the HomeViewController if the login is sucessful
let vc = self.storyboard?.instantiateViewController(withIdentifier: "Home")
self.present(vc!, animated: true, completion: nil)
} else {
//Tells the user that there is an error and then gets firebase to tell them the error
let alertController = UIAlertController(title: "Error", message: error?.localizedDescription, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: "OK", style: .cancel, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true, completion: nil)
}
}
}
}
Replace your code:
let vc = self.storyboard?.instantiateViewController(withIdentifier: "Home")
self.present(vc!, animated: true, completion: nil)
With this Code:
let vc : YourViewController = self.storyboard?.instantiateViewController(withIdentifier: "Home")as! YorViewController
let navController = UINavigationController(rootViewController: vc)
self.present(navController, animated: true, completion: nil)
You are just trying to present the view controller with out Navigation. Give it Navigation programmatically then it will show Navigation bar.
Are you really using navigationController? If so, should it be pushViewController rather than present?
navigationController?.pushViewController(vc, animated: true)
Related
I'm using the newest Xcode and Swift version.
I'm presenting a specific View Controller like this:
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let contactViewController = storyboard.instantiateViewController(identifier: "contactViewController")
show(contactViewController, sender: self)
I'm dismissing this View Controller like this:
self.presentingViewController?.dismiss(animated: true, completion: nil)
I want to present an UIAlertController right after dismissing the View Controller.
This:
self.presentingViewController?.dismiss(animated: true, completion: nil)
let alertMessage = UIAlertController(title: "Your message was sent", message: "", preferredStyle: .alert)
let alertButton = UIAlertAction(title: "Okay", style: UIAlertAction.Style.default)
alertMessage.addAction(alertButton)
self.present(alertMessage, animated: true, completion: nil)
… of course doesn't work because I cannot present an UIAlertController on a dismissed View Controller.
What's the best way to present this UIAlertController after the View Controller is dismissed?
You can do it in completion handler by getting top controller like this
self.presentingViewController?.dismiss(animated: true, completion: {
let alertMessage = UIAlertController(title: "Your message was sent", message: "", preferredStyle: .alert)
let alertButton = UIAlertAction(title: "Okay", style: UIAlertAction.Style.default)
alertMessage.addAction(alertButton)
UIApplication.getTopMostViewController()?.present(alertMessage, animated: true, completion: nil)
})
Using this extension
extension UIApplication {
class func getTopMostViewController() -> UIViewController? {
let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
if var topController = keyWindow?.rootViewController {
while let presentedViewController = topController.presentedViewController {
topController = presentedViewController
}
return topController
} else {
return nil
}
}
}
Use Jawad Ali's extension, we could anchor the current presented ViewController.
And if you want to dismiss that alert later, you could do it in another completion handler as below code showed. In my case, I save a song to one playlist and dismiss this playlist and show a short time alert to let user know that saving ok.
DispatchQueue.main.async {
self?.removeSpinner()
self?.dismiss(animated: true, completion: {
let alert = UIAlertController(title: "Save to playlist", message: nil, preferredStyle: .alert)
UIApplication.getTopMostViewController()?.present(alert, animated: true, completion: {
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { _ in
alert.dismiss(animated: true)
}
})
})
}
I was wondering if it is possible to push to a newViewController after pressing a button in the UiAlertController
my code looks like
#objc func handleAcceptRequest() {
let user = self.user
let username = user?.name
let alert = UIAlertController(title: "Are you Sure? ",message:" Would you like to accept \(username!) to complete your job?", preferredStyle: UIAlertController.Style.alert)
let cancelButton = UIAlertAction(title: "Cancel", style: .default, handler: {(_ action: UIAlertAction) -> Void in
print("you pressed cancel button")
})
let continueButton = UIAlertAction(title: "Continue", style: .default, handler: {(_ action: UIAlertAction) -> Void in
let vc = viewController()
let navController = UINavigationController(rootViewController: vc)
print("you pressed Continue")
})
continueButton.setValue(GREEN_Theme, forKey: "titleTextColor")
cancelButton.setValue(UIColor.red, forKey: "titleTextColor")
alert.addAction(cancelButton)
alert.addAction(continueButton)
self.window?.rootViewController?.present(alert, animated: true, completion: nil)
}
I would only like to present the VC if the the Continue button is pressed but If I call the present
// self.present(navController, animated: true, completion: nil)
inside of the continueButton, I get the error Use of unresolved identifier 'present'
is it possible to push a newVC this way?
This is not right
// self.present(navController, animated: true, completion: nil)
It should be:
self.window?.rootViewController?. present(navController, animated: true, completion: nil)
It is my function I linked to button. It doesn't push to another ViewController. It should work in following way : User clicks button, button creates alert, alert stays in current ViewController or pushes to different existing ViewController. No idea why it is not working - alert shows and nothing happens. Identifier is set and correct.
let alert = UIAlertController(title: "Warning", message: "Aborting adding a routine scheme. Proceed?", preferredStyle: .alert)
alert.addAction(.init(title: "No", style: .cancel, handler: nil))
alert.addAction(.init(title: "Yes", style: .default, handler: { (action) in
alert.dismiss(animated: true, completion: nil)
// push to another VC
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "WorkoutViewController") as! WorkoutViewController
self.navigationController?.pushViewController(vc, animated: true)
}))
self.present(alert, animated: true, completion: nil)
Your current ViewController isn't embed in UINavigationController so this line does nothing
self.navigationController?.pushViewController(vc, animated: true)
... because navigationController is nil
If you want to just present ViewController use this
self.present(vc, animated: true, completion: nil)
I want after signup the alert controller should pop up and then go the loginFirstViewController but this is not going to happen why?? it only goes to loginfirstviewcontroller instead of poping up alert controller
if error == nil {
FIRAuth.auth()?.currentUser!.sendEmailVerification(completion: { (error) in
})
print("You have successfully signed up")
//Goes to the Setup page which lets the user take a photo for their profile picture and also chose a username
let alertController = UIAlertController(title: "Successful!", message: "Email Verification link sent", preferredStyle: .alert)
let alertActionOkay = UIAlertAction(title: "Okay", style: .default)
let vc = self.storyboard?.instantiateViewController(withIdentifier: "LoginFirstViewController")
self.present(vc!, animated: true, completion: nil)
alertController.addAction(alertActionOkay)
self.present(alertController, animated: true, completion: nil)
}
You directly opened new viewcontroller to prevent this you should add completion handler for uialertaction. When the user press ok button you can open other viewcontroller
let alertController = UIAlertController(title: "Successful!", message: "Email Verification link sent", preferredStyle: .alert)
let alertActionOkay = UIAlertAction(title: "Okay", style: .default) { (action) in
let vc = self.storyboard?.instantiateViewController(withIdentifier: "LoginFirstViewController")
self.present(vc!, animated: true, completion: nil)
}
alertController.addAction(alertActionOkay)
self.present(alertController, animated: true, completion: nil)
I want to display a new ViewController but it's not works when a AlertController is displayed. (I don't want use existing segue, only in swift). Somebody could help me ?
It's just a simple example, in my app i use a custom AlertController who display a loader. So, i don't want to be redirect after click in alert button
Thanks in advance
Ps: Sorry about my bad english.
#IBAction func testButtonClick(_ sender: AnyObject) {
let alert = UIAlertController(title: nil, message: "test", preferredStyle: UIAlertControllerStyle.alert)
self.present(alert, animated: true, completion: nil)
logout()
}
func logout() {
let storyboardName = "Authentication"
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
if let newVC = storyboard.instantiateInitialViewController() {
newVC.modalPresentationStyle = UIModalPresentationStyle.fullScreen
self.present(newVC, animated: true)
} else {
print("Unable to instantiate VC from \(storyboardName) storyboard")
}
}
You can use in this way.
let alert = UIAlertController(title: nil, message: "test", preferredStyle: UIAlertControllerStyle.alert)
self.present(alert, animated: true, completion: nil)
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let newVC = storyboard.instantiateViewController(withIdentifier: "ChildViewController") as? ChildViewController
newVC?.modalPresentationStyle = UIModalPresentationStyle.fullScreen
presentedViewController?.present(newVC!, animated: true)
One of the options is that you could keep the alert in a var at the instance level, so that as a pre-requisite to your transition, it first closes it.
var alert: UIAlertController?
In testButtonClick:
alert = UIAlertController(title: nil, message: "test", preferredStyle: UIAlertControllerStyle.alert)
let completion = { self.alert = nil }
self.present(alert, animated: true, completion: completion)
In logout:
let completion = { self.alert = nil }
alert?.dismissViewController(animated: true, completion: completion)
Note: you can also make your life easy and use segues and prepareForSegue...