Eyal Ben Yehuda
Eyal Ben Yehuda

Reputation: 219

Tinder-like navigation in swift

i'm trying to use this framework that provides a navigation bar like Tinder's (Swift 3).

my goal is to use this in a transperant way - meaning - to embed it and have 3 independent view controllers on storyboard, with their VC.swift files and use segues.

Here is a working test project with Tinder style and 3 ViewControllers from Storyboard.

before using it in my project i wanted to test it so i updated this project.

As i saw, nav is the UINavigationController that have the 3 VC's and switching between them. i wanted to see him on the storyboard.

so insted of:

var nav: UINavigationController?

i created a UINavigationController on the UI builder and UINavigationController class called MainNavigationController.

var nav: MainNavigationController?
nav = mainStb.instantiateViewController(withIdentifier: "mainNavigationController") as? MainNavigationController

i also added a simple initial view controller to storyboard, from this VC i segue (using a button) to the MainNavigationController:

@IBAction func buttonSegue(_ sender: Any) {
        setNav()

        self.performSegue(withIdentifier: "segue", sender: nil)
    }

func setNav() {


    //// implement my logic (if logged in go to... if not go to...)

    instantiateControllers()
    setItems()

    let items = [UIImageView(image: chat),
                 UIImageView(image: gear),
                 UIImageView(image: profile)]

    let controllers = [oneVC!,
                       twoVC!,
                       threeVC!] as [UIViewController]

    controller = SLPagingViewSwift(items: items, controllers: controllers, showPageControl: false)

    setupController()


    nav = MainNavigationController(rootViewController: controller)
    appDelegate.window?.rootViewController = nav
    appDelegate.window?.makeKeyAndVisible()
}

it all works so far. BUT:

The only problem i currently have is that i don't have control on the segues. in the 3 view controllers i added

override func prepare(for segue: UIStoryboardSegue, sender: Any?)

but it is never hitting this method. i need it to pass data between view controllers. how can it be done?

Additionally, how would you implement a segue from one view controller to another by tapping an element (like a button)? if i set a regular segue, using a button, from one VC to another - it shows the target VC without the navigation bar

i uploaded my current implementation here.

any help will be appricieated. thanks.

Upvotes: 0

Views: 1058

Answers (1)

David Seek
David Seek

Reputation: 17132

Okay. I have downloaded your project, because your explanation wasn't really helpful..

First of all: If you have a storyboard with nothing but blank screens, color them for other coders to be able to tell faster what's going on.

enter image description here

Your segue from the yellow VC to the UINavigationController is triggered, but not used because you instantiate the UINavigationController programatically.

// Sets the root
func setNav() {
    // here        
    nav = MainNavigationController(rootViewController: controller)
    appDelegate.window?.rootViewController = nav
    appDelegate.window?.makeKeyAndVisible()
}

Your segue from the green VC to the blue VC doesn't make any sense because there is no segue. Those controllers are embedded into the same controller. You are setting up the perform(forSegue function, but you are never calling it. You only use perform(forSegue if there is a segue. But that is not the case.

Setting the button without the setNav() function:

@IBAction func buttonSegue(_ sender: Any) {
    //setNav()
    self.performSegue(withIdentifier: "segue", sender: nil)
}

Results in the blue VC as single VC.

enter image description here

Same function without the segue, results in the same logic, as with the segue. Because as said, you set up everything programatically anyways:

@IBAction func buttonSegue(_ sender: Any) {
    setNav()
    //self.performSegue(withIdentifier: "segue", sender: nil)
}

enter image description here

Since you have instantiated the VCs globally, you are able to get/set VCs values globally...

class OneVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    @IBAction func passData(_ sender: Any) {
        let oneVCString = "This String is passed from OneVC"
        twoVC?.theLabel.text = oneVCString
    }
}

And the outcome:

enter image description here

Here is this on Github as a fork of your project. Also I have deleted your code from the AppDelegate. Wasn't useful and called anyways. You did the same in the Interface Builder already.

Last but not least a comment from me: Clean up your code! Other users might have a different opinion on that, but this is not how I want to work with other coders:

import UIKit

class TwoVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        print("from two to...")
        print(segue.identifier!)
    }
    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}

Remove all the unnecessary comments.

Upvotes: 1

Related Questions