let SecondViewController =
self.storyboard?.instantiateViewController(withIdentifier:
"SecondViewController") as! SecondViewController
self.navigationController?.pushViewController(SecondViewController,
animated: true)
For some reason this doesn't work. Any ideas?
Replace
self.navigationController?.pushViewController(SecondViewController,
animated: true)
with
self.navigationController?.present(SecondViewController, animated: true, completion: nil)
Edit: To avoid the optionals you should also do one of the following:
guard let navController = self.navigationController else { return }
navController.present(SecondViewController, animated: true, completion: nil)
or
if let nacVontroller = self.navigationController {
navController.present(SecondViewController, animated: true, completion: nil)
}
Edit2: You should also avoid force unwrapping your SecondViewController using one of the above methods as well. Although that is not your current issue.
Related
I have the following delegate method that I activate on dismiss of a .formsheet - when it dismisses I need to popToViewController - it appears print("User Logged Out") is also not printing, what is being done incorrectly? I am primarily instructed in how to do this using delegates if possible.
View Controller 2
var delegate: LogoutDelegate?
func logout() {
print("Logout")
self.delegate?.didLogout()
dismiss(animated: true, completion: {
})
}
View Controller 1
protocol LogoutDelegate {
func didLogout() -> Void
}
func didLogout() -> Void {
print("User Logged Out")
self.navigationController?.popToRootViewController(animated: true)
}
Presenting ViewController2:
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Test") as! SettingsViewController
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .formSheet
self.present(navigationController, animated: true, completion: nil)
Assuming your ViewController2 is SettingsViewController, when you are preparing to present ViewController2, you need to set its delegate to your current viewController viewController1.
Sth like this:
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "Test") as! SettingsViewController
controller.delegate = self
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .formSheet
self.present(navigationController, animated: true, completion: nil)
Again, I'm assuming this code is in your VC1, so in this case self is your VC1.
I'm trying to present a new VC, but when I hit the code application get stuck and I can't do anything. It's quite a weird issue, how can I get out of it? My code for presenting new VC is this,
let vc : PropertyDetailController! =
UIStoryboard.viewController(identifier: "PropertyDetailController", storyBoard: "Explore") as? PropertyDetailController
vc.propertyDetailData = property
vc.hidesBottomBarWhenPushed = true
vc.modalTransitionStyle = .crossDissolve
vc.modalPresentationStyle = .fullScreen
self.navigationController?.present(vc, animated: true, completion: nil)
This is what it shows in console,
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
It isn't present new VC. This is how it my apps stuck please check gif link,
enter link description here
As I can see in your code you are moving to the new storyboard so it's necessary to move it on through the UINavigationController
Blow one is the sample code that might help you
let storyBoard: UIStoryboard = UIStoryboard(name: "YOUR_STORYBOARD", bundle: nil)
let aVC: YOUR_VC = storyBoard.instantiateViewController(withIdentifier: "YOUR_VC_ID") as! YOUR_VC
let navigationController = UINavigationController(rootViewController: aVC)
self.present(navigationController, animated: true, completion: nil)
if you want to present a view controller, try
self.present(vc, animated: true, completion: nil)
if you want to push a view controller, try
self.navigationController?.pushViewController(vc, animated: true)
Try moving the push code to main thread,
DispatchQueue.main.async {[weak self] in
self?.navigationController?.pushViewController(vc, animated: true)
}
Either present or push, all the UI handling must be done on the main thread.
Edit:
If you want to present vc, use
DispatchQueue.main.async {[weak self] in
self?.present(vc, animated: true, completion: nil)
}
First make sure current view controller embedded with Navigation Controller.
Now use below code to fix this issue.
let storyboard = UIStoryboard(name: "Explore", bundle: nil)
guard let vc = storyboard.instantiateViewController(withIdentifier: "PropertyDetailController") as? PropertyDetailController else {return}
vc.hidesBottomBarWhenPushed = true
vc.modalTransitionStyle = .crossDissolve
vc.modalPresentationStyle = .fullScreen
self.navigationController?.present(vc, animated: true, completion: nil)
I receive this error with the following code. I have a View Controller class called "testViewController". I'm trying to press a button and make it appear, but this error is showing in my code. Help!
self.present(testViewController, animated: true, completion: nil)
I expect this should show the new view controller but it does not.
You need to pass an instance not
let vc1 = TestViewController.self // wrong
let vc2 = TestViewController() // right
self.present(vc2, animated: true, completion: nil) // right
self.present(TestViewController, animated: true, completion: nil) // wrong
self.present(vc1, animated: true, completion: nil) // wrong
Edit: If the vc is inside storyboard load it like
let vc = self.storyboard!.instantiateViewController(withIdentifier: "VCID") as! TestViewController
self.present(vc1, animated: true, completion: nil) // right
I just found code that works. Thanks all. Here it is:
let testViewController = self.storyboard?.instantiateViewController(withIdentifier: "MyTest") as! testViewController // I created MyTest in the identifier field of the identity inspector.
self.present(testViewController, animated: true)
This is my Code
#IBAction func backButton(_ sender: UIButton) {
self.dismiss(animated: true, completion: { () -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
self.present(vc, animated: true, completion: nil)
})
}
this is not working only dissmising
I dont't understand your questions well. I think you want to present a new ViewController. You can use this:
UIView.animate{duration: 0.5, animations: {
(UIApplication.shared.delegate as! AppDelegate).window!.rootViewController = NextViewController()
}}
Problem is that you are dismissing self and then trying to present a new view controller on that exact same self - but at that moment self is already dismissed. You need to present that new view controller from the parent of the current view controller. I believe the best way is to setup a delegate. So the controller that you showed us and that you want to dismiss will have this:
protocol FirstDelegate: class {
func firstDismiss(_ first: First)
}
class First: UIViewController {
weak var delegate: FirstDelegate?
#IBAction func backButton(_ sender: UIButton) {
// this will tell the delegate to dismiss this contorller and present the other one
delegate?.firstDismiss(self)
}
// rest of the code omitted
}
Next, you will have to setup this in the parent that presents First view controller (here I assume that presentFirst method presents the First view controller):
class ParentViewController: UIViewController, FirstDelegate {
// rest of the code
func presentFirst() {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let firstVC = storyboard.instantiateViewController(withIdentifier: "First") as! RequestItemPackageDetails
// set delegate to first:
firstVC.delegate = self
self.present(firstVC, animated: true, completion: nil)
}
func firstDismiss(_ first: First) {
first.dismiss(animated: true, completion: { () -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
self.present(vc, animated: true, completion: nil)
})
}
}
Not quite sure with your Qns, but try this one out.
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
vc.previousVC = self
self.present(vc, animated: true)
RequestItemPackageDetails.swift
var previousVC : UIViewController!
override viewDidLoad() {
previousVC.dismiss(animated: false, completion: nil)
}
You can dismiss self and then present another view from rootViewController
self.dismiss(animated: true, completion: { () -> Void in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "RequestItemPackageDetails") as! RequestItemPackageDetails
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.window!.rootViewController?.present(vc, animated: true, completion: nil)
})
I get an error:
fatal error: unexpectedly found nil while unwrapping an Optional value
The didTapUserScreenButton() works fine though, the didTapChatControllerButton() gives the error. I'm thinking it might get the error because the didTapChatControllerButton() goes to a UiCollectionViewController? and the other works fine as it's going to a UITableViewController?.
func didTapChatControllerButton() {
let chat_log_controller = ChatLogController
let navController = UINavigationController(rootViewController: chat_log_controller!)
present(navController, animated: true, completion: nil)
}
func didTapUserScreenButton() {
let user_screen_vc = usersScreenVC()
let navController = UINavigationController(rootViewController: user_screen_vc)
present(navController, animated: true, completion: nil)
You missed the (currently empty) initialization argument holder brackets. Try with tris:
let chat_log_controller = ChatLogController()
let navController = UINavigationController(rootViewController: chat_log_controller)
present(navController, animated: true, completion: nil)