I have two viewControllers:
1/ LoginViewController
2/ BibliothequeViewController
I am presenting BibliothequeViewController by clicking on a button inside LoginViewController and in the same time trying to communicate to BibliothequeViewController that it was LoginViewController that presented it.
So inside LoginViewController, I have this:
#IBAction func onLibrariesButtonClicked(_ sender: Any) {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let vc: BibliothequesViewController = storyboard.instantiateViewController(withIdentifier: "BibliothequesViewController") as! BibliothequesViewController
BibliothequesViewController.sharedInstance.presentedBy=self
print("INSIDE LoginViewController.onLibrariesButtonClicked, BibliothequesViewController.sharedInstance.presentedBy",BibliothequesViewController.sharedInstance.presentedBy!)
// Logs LoginViewController
self.present(vc, animated: true, completion: nil)
}
Inside BibliothequesViewController, I have this:
class BibliothequesViewController: UIViewController {
// presentedBy represents which view has presented the BibliothequesViewController
// So that when a library is selected, I go back to the ViewController that presented BibliothequesViewController
var presentedBy: UIViewController?
override func viewDidLoad() {
super.viewDidLoad()
print("INSIDE viewDidLoad, presentedBy: ",presentedBy)
// Logs nil
}
}
So as you see, in the LoginViewController code, BibliothequesViewController.sharedInstance.presentedBy has been set to LoginViewController.
But inside BibliothequeViewController, it is nil, when it should be LoginViewController.
I tried this:
print("INSIDE BibliothequesViewController, BibliothequesViewController.sharedInstance.presentedBy",BibliothequesViewController.sharedInstance.presentedBy!)
And I got LoginViewController logged. So I got what I needed.
But I expected the code above to work too.
Related
I have two view controller
imag
1.first view controller is main and second is CustomAlertviw controller
main view controller is like above image, when I click continues am showing the customalertview controller, like image. when click the enter pin button I have to dismiss view contoller and show the view controller with uiview on main view controller but tried, it's showing the view controller, there one more custom view is not showing it crashing my app
main view code
#IBAction func backButtonClicked(_ sender: UIButton) {
let myAlert = UIStoryboard(name: "CustomAlertview", bundle: nil).instantiateViewController(withIdentifier: "CustomAlertViewController") as? CustomAlertViewController
myAlert?.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert?.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
self.present(myAlert!, animated: true, completion: nil)
}
Customalertview controller
#IBAction func enterPinButtonClick(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
let myAlert = UIStoryboard(name: "ScanAndPay", bundle: nil).instantiateViewController(withIdentifier: "ScanAndPayDetailsEntryViewController") as? ScanAndPayDetailsEntryViewController
myAlert?.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert?.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
self.present(myAlert!, animated: true, completion: nil)
myAlert.valuespass()
}
inside main view controller one function calling from the customalrerview
func valuespass()
{
DispatchQueue.main.async {
self.authType = 1
self.authStatus = false
print("this is calling")
self.pinStatusLabel.text = "Please enter a 4-digit Security PIN"
}
when I am calling this function from the custom alert view application is crashing and showing the hread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value this error. how to can show the all information after dismissing the custom view controller.
You are almost done. present ScanAndPay from FirstView instead of CustomAlertview.
I have done using Delegate as I think it will be fit in this scenario. Follow below steps -
Step 1:
In FirstViewController ,
Add - CustomAlertviewDelegate something like this -
class FirstViewController: UIViewController, CustomAlertviewDelegate {
Now replace your backButtonClicked method -
#IBAction func backButtonClicked(_ sender: UIButton) {
let myAlert = UIStoryboard(name: "CustomAlertview", bundle: nil).instantiateViewController(withIdentifier: "CustomAlertViewController") as? CustomAlertViewController
myAlert?.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert?.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
myAlert.delegate = self
self.present(myAlert!, animated: true, completion: nil)
}
Add a new Delegate method of CustomAlertviewDelegate -
func ScanAndPayView(){
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
let myAlert = UIStoryboard(name: "ScanAndPay", bundle: nil).instantiateViewController(withIdentifier: "ScanAndPayDetailsEntryViewController") as? ScanAndPayDetailsEntryViewController
myAlert?.modalPresentationStyle = UIModalPresentationStyle.overCurrentContext
myAlert?.modalTransitionStyle = UIModalTransitionStyle.crossDissolve
self.present(myAlert!, animated: true, completion: nil)
}
}
Step 2:
Now time for CustomAlertview ,
Add protocol for delegate top of the Class -
protocol CustomAlertviewDelegate: class {
func ScanAndPayView()
}
class CustomAlertview: UIViewController{
weak var delegate : CustomAlertviewDelegate!
...
override func viewDidLoad() { // Rest of your code
}
Now time to dismiss current view controller and notify FirstViewController for presenting ScanAndPay view Controller -
#IBAction func enterPinButtonClick(_ sender: Any) {
delegate.ScanAndPayView()
self.dismiss(animated: true, completion: nil)
}
Hope it will help you to achieve what you want.
I'm in trouble, after that I'm moving from View Controller to a second View Controller and then switching back to the View Controller and clicking on the UI Image Picker it's not appearing and bringing me back to the second View Controller. On the debugger it's appearing:
Attempt to present on whose view is not in the window hierarchy!
I'm really becoming crazy. My code that is bringing me back from second View Controller to the first View Controller is inside a button and it's below:
#IBAction func profileButton(_ sender: Any) {
let webVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") as! ViewController
webVC.profileLink = linkProfilo
self.present(webVC, animated: false, completion: nil)
}
in second view controller add this variable:
var firstVC: ViewController?
and this setter function to set it
setup(firstVC: ViewController) {
self.firstVC = firstVC
}
in the first view controller, when presenting second view controller pass in a reference to self (first view controller)by calling the setup function
let secondVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "SecondViewController") as! ViewController
secondVC.setup(firstVC: self)
self.present(secondVC, animated: false, completion: nil)
now when button is clicked in secondVC,
guard let first = self.firstVC else {return}
first.profileLink = linkProfilo
self.dismiss(animated: false, completion: nil)
I finally found the way for fix all of this:
#IBAction func profileButton(_ sender: Any) {
if let webVC = UIStoryboard.init(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ViewController") as? ViewController {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
webVC.profileLink = linkProfilo
dismiss(animated: false, completion: nil)
appDelegate.window?.rootViewController!.present(webVC, animated: false, completion: nil)
}
}
it's enough to add the appDelegate sharing method and dismiss before to present the webVC for share the data in the right way and don't cause problems on the first view when presented.
There is HomeViewController as main viewController and LeftMenuViewController presented modally over current context. Now in LeftMenuViewController there is option to open ProfileViewController but I don't want to show ProfileViewController over LeftMenuViewController, So used this code but it is not working for some unknown reason, LeftViewController is dismissed but ProfileViewController is not pushed to front.
#IBAction func editAction(_ sender: Any) {
let homeVC:HomeViewController = self.presentingViewController!.childViewControllers[0] as! HomeViewController
self.dismiss(animated: false) {
DispatchQueue.global().async {
let infoVC:ProfileViewController = self.storyboard?.instantiateViewController(withIdentifier: "ProfileViewController") as! ProfileViewController
homeVC.navigationController?.pushViewController(infoVC, animated: true)
}
}
}
Any suggestion will be very helpfull
Change
DispatchQueue.global()
To
DispatchQueue.main
UI operations should be put in main queue
For this problem, the view controller in which this code is run is in the Login.storyboard IB file. The view controller I am trying to present is in the Main.storyboard IB file. The code below is what I'm using to transition from one view controller to another.
func presentNextView() {
let mainSb: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let screenAfterLogin: UIViewController = mainSb.instantiateViewControllerWithIdentifier("MainContainerView") as! UIViewController
self.presentViewController(screenAfterLogin, animated: true, completion: nil)
}
Running the application, I set 3 breakpoints on the 3 lines executed in the presentNextView function. Line one is called, line two is called, but line three is NOT called, and the next screen is not presented. Is there something wrong with xCode at the moment?
Checkout the project on github: https://github.com/joshuarcher/RecallBeta
Problem lies in file "HardLoginViewController.swift"
func presentNextView() {
let mainSb: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let screenAfterLogin: SecondVC = mainSb.instantiateViewControllerWithIdentifier("SecondVC") as SecondVC
let navigationController = UINavigationController(rootViewController: screenAfterLogin)
presentViewController(navigationController, animated: true, completion: nil)
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
presentNextView()
}
func presentNextView() {
let mainSb: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let screenAfterLogin: SecondVC = mainSb.instantiateViewControllerWithIdentifier("SecondVC") as SecondVC
let navigationController = UINavigationController(rootViewController: screenAfterLogin)
presentViewController(navigationController, animated: true, completion: nil)
}
}
import UIKit
class SecondVC: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.title="Second Screen"
}
}
I'm trying to code a button that simply switches to the next view. So I embedded the first ViewController into a navigation controller then I dragged in another view controller, created a new class name ViewController2 and associated that class with the second ViewController and came the second view controller a storyboard id:"view2". Then in the Button's function I added this code:
#IBAction func newGamePressed(sender: AnyObject) {
let view2 = self.storyboard?.instantiateViewControllerWithIdentifier("view2") as
ViewController2
self.navigationController?.pushViewController(view2, animated: true)
}
However when i click on the button, literally nothing happens!!! what am i doing wrong???
#IBAction func newGamePressed(sender: AnyObject) {
let VC1 = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("view2")
let navController = UINavigationController(rootViewController: VC1)
self.presentViewController(navController, animated:true, completion: nil)
}
Just try with this code.