0

I am using storyboard for ScreenOne, and I did not use the storyboard for ScreenTwo, I was coding as programmatically and until now no problem for me, but I am still not success to declare "storyboardIdentifier" for ScreenTwo. Here there is an example but I don't understand how I will handle this example inside of the app. Any idea will be appreciated.

Screenshot:

enter image description here

ScreenTwo:

class ForgotPasswordEmailCheckController: UIViewController {
  var storyboardId: String {
    return (value(forKey: "ForgotPasswordEmailCheckController") as? String)!
  }
  • Does this answer your question? [Segue without StoryBoard](https://stackoverflow.com/questions/52524596/segue-without-storyboard) – EmilioPelaez Jul 04 '21 at 17:50
  • @EmilioPelaez, I was try it also, but did not solved. I know many similar question but they are help to solve –  Jul 04 '21 at 17:52
  • please share code where u are initializing screenTwo programatically – abh Jul 04 '21 at 18:07
  • @abh, hold on pls I will update :) –  Jul 04 '21 at 18:15

2 Answers2

1

Storyboard Controller (Also Embed this controller in Navigation Controller):

class FirstVC: UIViewController {
    @IBOutlet weak var btn: UIButton!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        btn.addAction(UIAction(handler: { action in
            
            let secondVC = SecVC()
            self.navigationController?.pushViewController(secondVC, animated: true)
        }), for: .touchUpInside)
    }
}

Second Viewcontroller:

class SecVC: UIViewController {
        
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = UIColor.blue
    }
}
RTXGamer
  • 3,215
  • 6
  • 20
  • 29
  • let me try , tnx :) –  Jul 04 '21 at 18:20
  • btn? where did u declared? –  Jul 04 '21 at 18:40
  • In your first view controller. don't forget to embed it in the navigation controller or it won't navigate. – RTXGamer Jul 04 '21 at 18:47
  • 1
    so sorry I didnt get it very well, is it possible u update ur answer? I declared btn.addAction... inside of the SecVC, but how I will declare btn, in where ? –  Jul 04 '21 at 18:52
  • it is running but when I click the btn it throw error as "Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SegueApp.ViewController btn:]: unrecognized selector sent to instance 0x7f819ce08690'" –  Jul 04 '21 at 19:03
  • Is there any segue attached to it for some other VC. If it's for learning put it on git. – RTXGamer Jul 04 '21 at 19:20
  • yes sure I was check but still says "Thread 1: "-[SegueApp.ViewController btn:]: unrecognized selector sent to instance 0x7f7fc0607260"" –  Jul 04 '21 at 19:26
  • now not crash, but when I click btn not open SecondView, no action –  Jul 04 '21 at 19:42
  • Have you embedded the viewcontroller in Navigation Controller? – RTXGamer Jul 04 '21 at 19:43
  • @How , can U expain a bit –  Jul 04 '21 at 19:57
  • Select the controller on the Storyboard, then Click on Editor > Embed In > Navigation Controller – RTXGamer Jul 04 '21 at 20:01
  • Did you debug it? is 'pushViewController' getting called? – RTXGamer Jul 04 '21 at 20:13
  • it is running but not and motion. here it is " btn.addAction(UIAction(handler: { action in let secondVC = SecondView() self.navigationController?.pushViewController(secondVC, animated: true) }), for: .touchUpInside)" –  Jul 04 '21 at 20:15
  • It should work now. Can't tell what went wrong, add the repo to git then. – RTXGamer Jul 04 '21 at 20:22
  • Yes it run, but I dont know where I miss:) tnx so much for ur great help, I will add github and share here:) –  Jul 04 '21 at 20:34
0

This is programmatically way to do it:

in sceneDelegate set your initial navigation controller:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    
    window = UIWindow(windowScene: windowScene)
    window?.makeKeyAndVisible()
    let controller = UINavigationController(rootViewController: MyController())
    window?.rootViewController = controller
}

now configure your navigationBar in firstController, use my extension to do it:

extension UIViewController {

func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
    
    if #available(iOS 13.0, *) {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.backgroundColor = backgoundColor
        
        navigationController?.navigationBar.standardAppearance = navBarAppearance
        navigationController?.navigationBar.compactAppearance = navBarAppearance
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
        
        navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
        navigationItem.largeTitleDisplayMode = .always
        navigationController?.navigationBar.tintColor = tintColor
        navigationItem.title = title
        
    } else {
        // Fallback on earlier versions
        navigationController?.navigationBar.barTintColor = backgoundColor
        navigationController?.navigationBar.tintColor = tintColor
        navigationController?.navigationBar.isTranslucent = false
        navigationItem.title = title
    }
  }
}

This is your first controller looks like:

class MyController: UIViewController {

let button = UIButton() // declare your button

override func viewDidLoad() {
    super.viewDidLoad()
    
    configureNavigationBar(largeTitleColor: .white, backgoundColor: .black, tintColor: .white, title: "My Vc", preferredLargeTitle: true) // set nav bar with exetnsion
    
    view.backgroundColor = .white
        
    view.addSubview(button)
    button.backgroundColor = .systemBlue
    button.layer.cornerRadius = 9
    button.setTitle("My Button", for: .normal)
    button.addTarget(self, action: #selector (handelGoToSecondVc), for: .touchUpInside)
    button.translatesAutoresizingMaskIntoConstraints = false
    
    button.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16).isActive = true
    button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16).isActive = true
    button.heightAnchor.constraint(equalToConstant: 50).isActive = true
    button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
    
}
    
@objc func handelGoToSecondVc() {
    let controller = SecondController()
    controller.title = "second Vc"
    navigationController?.pushViewController(controller, animated: true)
 }
}

second controller:

class SecondController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .green
 }
}

This is the result:

enter image description here

Complete code:

import UIKit

class MyController: UIViewController {

let button = UIButton() // declare your button

override func viewDidLoad() {
    super.viewDidLoad()
    
    configureNavigationBar(largeTitleColor: .white, backgoundColor: .black, tintColor: .white, title: "My Vc", preferredLargeTitle: true) // set nav bar with exetnsion
    
    view.backgroundColor = .white
        
    view.addSubview(button)
    button.backgroundColor = .systemBlue
    button.layer.cornerRadius = 9
    button.setTitle("My Button", for: .normal)
    button.addTarget(self, action: #selector (handelGoToSecondVc), for: .touchUpInside)
    button.translatesAutoresizingMaskIntoConstraints = false
    
    button.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16).isActive = true
    button.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16).isActive = true
    button.heightAnchor.constraint(equalToConstant: 50).isActive = true
    button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -10).isActive = true
    
}
    
@objc func handelGoToSecondVc() {
    let controller = SecondController()
    controller.title = "second Vc"
    navigationController?.pushViewController(controller, animated: true)
 }
}

class SecondController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.backgroundColor = .green
 }
}

extension UIViewController {

func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
    
    if #available(iOS 13.0, *) {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.backgroundColor = backgoundColor
        
        navigationController?.navigationBar.standardAppearance = navBarAppearance
        navigationController?.navigationBar.compactAppearance = navBarAppearance
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
        
        navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
        navigationItem.largeTitleDisplayMode = .always
        navigationController?.navigationBar.tintColor = tintColor
        navigationItem.title = title
        
    } else {
        // Fallback on earlier versions
        navigationController?.navigationBar.barTintColor = backgoundColor
        navigationController?.navigationBar.tintColor = tintColor
        navigationController?.navigationBar.isTranslucent = false
        navigationItem.title = title
    }
  }
}
Fabio
  • 5,432
  • 4
  • 22
  • 24
  • tnx so much, where I will use extension UIViewController {}...? –  Jul 05 '21 at 08:06
  • @Skysoft13 copy and paste it below of your controller class... I update my answer with complete code. – Fabio Jul 05 '21 at 08:12
  • it is work like that tnx so much, but if you look at question, my ViewController not programatically, I have storyboard and SecondView controller wrote programatically. if you look at other answer it is according to my question but it is not working, is it possible we apply like it? –  Jul 05 '21 at 08:25
  • @Skysoft13 For sure! configure nav bar using my extension, set the start nav controller in sceneDelegate (simply substitute the name of controller, es.: remove MyController() and paste in ViewController() ), delete my button declaration, and its settings and constraints in viewDidLoad and use your IBOutlet and its settings and constraints, set button target like my code... If you want my advice, do it programmatically, you will have total control of your objects in the scene... – Fabio Jul 05 '21 at 08:41
  • I want to use @IBOutlet for button, button but How I will handle "@objc func handelGoToSecondVc() { let controller = SecondController() controller.title = "second Vc" navigationController?.pushViewController(controller, animated: true) } }" for btn, yes ı AGREE with u the best way programmatically, but for this project I have to use storyboard, that is way :) –  Jul 05 '21 at 08:49
  • @Skysoft13 You must create a IBOutlet action and copy in all handelGoToSecondVc func body: let controller = SecondController() controller.title = "second Vc" navigationController?.pushViewController(controller, animated: true) – Fabio Jul 05 '21 at 09:00
  • I update like that " @IBAction func btnn(_ sender: Any) { func handelGoToSecondVc() { let controller = SecondController() controller.title = "second Vc" navigationController?.pushViewController(controller, animated: true) } }" it is build but throw this error " Unbalanced calls to begin/end appearance transitions for ." –  Jul 05 '21 at 09:13
  • No, did you link the function to the button? If you do it: @IBAction func btnn(_ sender: Any) { let controller = SecondController() controller.title = "second Vc" navigationController?.pushViewController(controller, animated: true)} For more I need to see your project, my answer is for programmatically do it... – Fabio Jul 05 '21 at 09:17
  • I update like that " @IBAction func butto(_ sender: Any) { let controller = SecondController() controller.title = "second Vc" navigationController?.pushViewController(controller, animated: true) }" still throw like that error " Unbalanced calls to begin/end appearance transitions for ." I am just see black screen green top navigation bar –  Jul 05 '21 at 09:26
  • @Skysoft13 I put in Mega a example project for you... https://mega.nz/folder/Bh8GAJyB#023RHIs-3A60FG_KByxyHw – Fabio Jul 05 '21 at 09:44
  • 1
    tnx so so so much, I appreciated ur great help, tnx so much :) –  Jul 05 '21 at 09:48