Swift NavigationController push method request doesn't work from PopUp view - swift

The new PopUp ViewController is presented .overCurrentContext
There are 2 buttons with navigation for 2 other views from PopUp view.
A simple action such as print goes well, but when I try to segue programmatically (from xib file, popUpViewController) nothing happens.
let vc = RegisterEmailViewController.instantiate()
vc.coordinator = self
navigationController.pushViewController(vc, animated: false)
Goes well from any other view.
What could be wrong?
PopUpViewController code:
// Created by ᴀʟᴇxᴀɴᴅʀ ᴢʜᴇʟɪᴇᴢɴɪᴀᴋ on 23.12.2019.
// Copyright © 2019 ᴀʟᴇxᴀɴᴅʀ ᴢʜᴇʟɪᴇᴢɴɪᴀᴋ. All rights reserved.
import UIKit
class ViewController: UIViewController, Storyboarded {
weak var coordinator: MyCoordinator?
#IBAction func dismissPopUp(_ sender: Any) {
dismiss(animated: false, completion: nil)
}
#IBAction func buttonEmail(_ sender: Any) {
let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "EmailViewController") as? EmailViewController
self.navigationController?.pushViewController(vc!, animated: true)
}
#IBAction func buttonPhone(_ sender: Any) {
let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "PhoneViewController") as? PhoneViewController
self.navigationController?.pushViewController(vc!, animated: true)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}

There is MyCoordinator which inits all navigations and doesn't let me simply to segue/navigate by my own.
var childCoordinators = [Coordinator]()
var navigationController: UINavigationController
init(navigationController: UINavigationController) {
self.navigationController = navigationController
}
Therefore, a reference to the controller solved the issue. It is possible to navigate aside, until new subViews, separate views are called.
Code that worked in this case:
let vc = RegisterEmailViewController.instantiate()
vc.coordinator = self
navigationController.pushViewController(vc, animated: false)
Conclusion. Simple there are two ways:
To delete all dependencies and other methods which use
UINavigationController
To declare only by new methods for global usage.

Related

Prepare For Segue on return

So the code I am trying to implement in Swift is based upon this answer here for passing data back from a ViewController:
Passing Data with a Callback
Now my issue is after I have called:
self.navigationController?.popViewController(animated: true)
The Prepare For Segue function isn't called in my original View Controller. I assume it shouldn't be called anyway but from that answer I assume there is a possible way to do so?
First View Controller Snippets
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//ignore this segue identifier here, this function works when I am showing a new VC
if(segue.identifier == "certSegue"){
let certVC = segue.destination as! CertificateViewController
certVC.profileModel = profileModel
}
//this is what I need to be called
if(segue.identifier == "dpSegue"){
print("dpSegue")
let dpVC = segue.destination as! DatePickerViewController
dpVC.callback = { result in
print(result)
print("Data")
// do something with the result
}
//dpVC.dailyBudgetPassedThrough = "Test"
}
}
func showDatePicker(){
let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "DatePickerVC") as? DatePickerViewController
self.navigationController?.pushViewController(vc!, animated: true)
}
Second View Controller
import UIKit
class DatePickerViewController: UIViewController {
var callback : ((String)->())?
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func sendBackUpdate(){
print("Callback")
callback?("Test")
}
#IBAction func cancelButton(_ sender: Any) {
self.navigationController?.popViewController(animated: true)
}
#IBAction func updateButton(_ sender: Any) {
sendBackUpdate()
self.navigationController?.popViewController(animated: true)
}
}
prepareForSegue is called if in Interface Builder a segue is connected
from a table/collection view cell to a destination view controller and the cell is tapped.
from a source view controller to a destination view controller and performSegue(withIdentifier:sender:) is called in the source view controller.
It's not called when a view controller is going to be presented with pushViewController
In your case assign the callback after instantiating the controller in showDatePicker, prepare(for segue is not needed.
func showDatePicker(){
let vc = UIStoryboard(name: "Main", bundle: .main).instantiateViewController(withIdentifier: "DatePickerVC") as! DatePickerViewController
vc.callback = { result in
print(result)
print("Data")
// do something with the result
}
self.navigationController?.pushViewController(vc, animated: true)
}

Segue to another Storyboard with NavigationController

I'm trying to fix an onboarding/walkthrough to my app. Everything works as it should, except that when I navigate to the first page, navigationController disappears.
When I close the app and start it again, there is NavigationController/bar there.
is there something wrong in my code?
#IBAction func buttonPressed(_ sender: Any) {
let storyborad = UIStoryboard(name: "Main", bundle: nil)
let mainVC = storyborad.instantiateViewController(withIdentifier: "mainVC") as! ViewController
self.present(mainVC, animated: true, completion: nil)
}
You need to present your VC with a UINavigationController, or push a new VC onto the current navigationController.
First approach pushing mainVC to current navigationController (Probably will work better in your case):
#IBAction func buttonPressed(_ sender: Any) {
let storyborad = UIStoryboard(name: "Main", bundle: nil)
let mainVC = storyborad.instantiateViewController(withIdentifier: "mainVC") as! ViewController
self.navigationController?.pushViewController(mainVC, animated: true)
}
Second approach, presenting with initializing a navigationController:
#IBAction func buttonPressed(_ sender: Any) {
let storyborad = UIStoryboard(name: "Main", bundle: nil)
let mainVC = storyborad.instantiateViewController(withIdentifier: "mainVC") as! ViewController
self.present(UINavigationController(rootViewController: mainVC), animated: true, completion: nil)
}

xcode swift4 how do I change the page in viewdidload

I cannot use segue on viewDidLoad.
I already check the segue is worded on another func.
When load the view check some condition then change view this is what I want.
override func viewDidLoad(){
super.viewDidLoad()
performSegue(withIdentifier: "go" , sender: self)
}
If you want to push your view controller on view did load then just use this code.
let storyBoard : UIStoryboard = UIStoryboard(name: "your_StoryBoard", bundle:nil)
let nextViewController = storyBoard.instantiateViewController(withIdentifier: "VC_Identifier") as! TargerViewController
self.navigationController?.pushViewController(nextViewController, animated: true)
OR
You can set the target viewcontroller as root viewcontroller by check any condition.
Hope it will helps you out.
i prefer that don't use segue use as below
let storyboard = UIStoryboard(name: "YourStoryboard", bundle: nil)
let VC = storyboard.instantiateViewController(withIdentifier: "Your Identifier") as! Your ViewController
self.present(VC, animated:true, completion:nil)
user this for redirect from One VC To Another VC
Replace viewDidLoad to viewDidAppear solved my problem
override func viewDidAppear() {
super.viewDidLoad()
performSegue(withIdentifier: "go" , sender: self)
}

Storyboard initialization and deinit

When initializing a ViewController via a Storyboard (NS or UI), do you need to keep a reference to the storyboard or can you just ignore it when you are done with it and let it deinit?
class ViewController: NSViewController {
var secondarySB: NSStoryboard? = nil
#IBAction
func loadAndKeep(_ sender: NSButton) {
//keeping a reference
secondarySB = NSStoryboard.init(name: NSStoryboard.Name.init(rawValue: "Secondary"), bundle: nil)
let vc = secondarySB?.instantiateInitialController() as! Secondary
self.view.addSubview(vc.view)
}
#IBAction
func load(_ sender: NSButton) {
//ignoring the storyboard after I get the viewcontroller
let sb = NSStoryboard.init(name: NSStoryboard.Name.init(rawValue: "Secondary"), bundle: nil)
let vc = sb.instantiateInitialController() as! Secondary
self.view.addSubview(vc.view)
}
}
You do not need to keep a reference to the storyboard, but you do need to add the instantiated view controller as a child view controller.

How do i load a viewcontroller from a xib file?

I tried to load a viewcontroller from a custom cell using delegates.But i get nil from the set delegate!
Here is a sample if anyone can help!
1. In Cell
protocol hotelFindDelegate{
func modalDidFinished(modalText: String)
}
class hotelFindCell: UITableViewCell {
var delegate:hotelFindDelegate?
#IBAction func findButton(sender: AnyObject) {
self.delegate!.modalDidFinished("HELLO")
print("Damn nothing works")
}
2. In Main View
class MainViewController:hotelFindDelegate {
let modalView = hotelFindCell()
override func viewDidLoad() {
super.viewDidLoad()
self.modalView?.delegate = self
}
func modalDidFinished(modalText: String){
let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("HotelListVC") as UIViewController
self.presentViewController(viewController, animated: false, completion: nil)
self.modalView.delegate = self
print(modalText)
}
To load view controller from XIB do the following steps.
let settingVC : SettingsViewController = SettingsViewController(nibName :"SettingsViewController",bundle : nil)
later on you can push the same view controller object like
self.navigationController?.pushViewController(settingsVC, animated: true)
NSBundle.mainBundle().loadNibNamed("viewController", owner: self, options: nil)