user12688502
user12688502

Reputation:

Dynamically assign ViewController to Navigate

In my case I have UITableView and have View all button for the listing of all the items in separate screens. So I added target for UIButton action method in cellForRowAt. Now what I am doing in action method:

@IBAction func btnViewAllOffer(_ sender: UIButton) {
        let buttonPosition = sender.convert(CGPoint.zero, to: self.tblOfferView)
        let indexPath = self.tblOfferView.indexPathForRow(at: buttonPosition)

        if indexPath != nil {

            if let type = self.homeData[indexPath!.section].type {
                if type == HomeDataType.SponserProduct.rawValue {
                    let vc1 = self.storyboard?.instantiateViewController(withIdentifier: "ViewController1") as! ViewController1
                    if let title = self.homeData[indexPath!.section].title {
                        vc1.title = title
                    }
                    self.navigationController?.pushViewController(vc1, animated: true)
                } else if type == HomeDataType.Offer.rawValue {
                    let vc2 = self.storyboard?.instantiateViewController(withIdentifier: "ViewController2") as! ViewController2
                    if let title = self.homeData[indexPath!.section].title {
                        vc2.title = title
                    }
                    self.navigationController?.pushViewController(vc2, animated: true)
                } else if type == HomeDataType.BestSeller.rawValue {
                    let vc3 = self.storyboard?.instantiateViewController(withIdentifier: "ViewController3") as! ViewController3
                    if let title = self.homeData[indexPath!.section].title {
                        vc3.title = title
                    }
                    self.navigationController?.pushViewController(vc3, animated: true)
                }
            }
        }
    }

What I need, is there any way I can minimize the code and assign viewcontrollers dynamically so there is no need to instantiate each view controller and push them everytime? Something like:

var vc = UIViewController()
if let type = self.homeData[indexPath!.section].type {
    if type == HomeDataType.SponserProduct.rawValue {
        vc = ViewController1()
    }
    else if type == HomeDataType.Offer.rawValue {
        vc = ViewController2()
    } else if type == HomeDataType.BestSeller.rawValue {
        vc = ViewController3()
    }
}
self.navigationController?.pushViewController(vc, animated: true)

Upvotes: 2

Views: 94

Answers (3)

Chetan Hedamba
Chetan Hedamba

Reputation: 291

Create BaseViewController and derived other ViewController from BaseViewController

class BaseViewController: UIViewController {
    var viewTitle = ""
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

    }

    func pushVC(_ vcName : String) {
        let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: vcName)

        self.navigationController?.pushViewController(vc, animated: true)
    }
}

And use below code on ViewController you need like:

@IBAction func btnViewAllOffer(_ sender: UIButton) {
        let buttonPosition = sender.convert(CGPoint.zero, to: self.tblOfferView)
        let indexPath = self.tblOfferView.indexPathForRow(at: buttonPosition)

        if indexPath != nil {

            if let type = self.homeData[indexPath!.section].type {
                self.viewTitle = self.homeData[indexPath!.section].title
                if type == HomeDataType.SponserProduct.rawValue {
                    self.pushVC("ViewController1")
                } else if type == HomeDataType.Offer.rawValue {
                    self.pushVC("ViewController2")
                } else if type == HomeDataType.BestSeller.rawValue {
                    self.pushVC("ViewController3")
                }
            }
        }
    }

Upvotes: 0

denis_lor
denis_lor

Reputation: 6547

Use a protocol (SimilarViewController) to define the common properties like title:

protocol SimilarViewController {
    var title: String? { get set }
}

class ViewController1: UIViewController, SimilarViewController {
    var title: String?
}
class ViewController2: UIViewController, SimilarViewController {
    var title: String?
}
class ViewController3: UIViewController, SimilarViewController {
    var title: String?
}


@IBAction func btnViewAllOffer(_ sender: UIButton) {
        let buttonPosition = sender.convert(CGPoint.zero, to: self.tblOfferView)
        let indexPath = self.tblOfferView.indexPathForRow(at: buttonPosition)

        if indexPath != nil {

            if let type = self.homeData[indexPath!.section].type {
                var vcGeneric: SimilarViewController?

                if type == HomeDataType.SponserProduct.rawValue {
                    vcGeneric = self.storyboard?.instantiateViewController(withIdentifier: "ViewController1") as! ViewController1
                } else if type == HomeDataType.Offer.rawValue {
                    vcGeneric = self.storyboard?.instantiateViewController(withIdentifier: "ViewController2") as! ViewController2
                } else if type == HomeDataType.BestSeller.rawValue {
                    vcGeneric = self.storyboard?.instantiateViewController(withIdentifier: "ViewController3") as! ViewController3
                }


                if let title = self.homeData[indexPath!.section].title {
                    vcGeneric?.title = title
                }

                if let vcGeneric = vcGeneric  as? UIViewController {
                    self.navigationController?.pushViewController(vcGeneric, animated: true)
                }
            }
        }
}

Upvotes: 1

Keshu R.
Keshu R.

Reputation: 5225

1: create a struct and assign the value to it.

    struct TitleDetails { 
         static var title : String = ""
    }

2: create an extension of viewController and use it to avoid code repetition.

    extension UIViewController {

        func pushVC(_ vcName : String) {
            let vc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: vcname)
            self.navigationController?.pushViewController(vc, animated: true)
        }
    }

3: now you can call it directly as,

TitleDetails.title = yourTitleValue
self.pushVC("ViewController1")

and in your ViewDidLoad() method of your destination view controller,

self.title = TitleDetails.title

Upvotes: 0

Related Questions