I am working with a UIPageViewController
, which has five view controllers in the storyboard and I created a class for each view controller. It all works fine, however I am looking to improve my code as the five view controllers are identical in almost everything (they all contain a table view and only differ in the information displayed by it).
I am looking to have one view controller inside my page view controller and create five instances of that view controller, rather than having to repeat my code five times.
I know that it is possible to instantiate multiple view controllers with the same storyboard identifier, hence create multiple instances of one view controller class, but my question is how to manage the properties of each instance. For example, if I need to change table view background colour?
Thank you in advance.
This is absolutely the way you should be addressing this.
Even if you have some differences between the controllers, if the majority of the functionality is the same, then you can use a single class.
All you need to do is set a class-level variable to identify which controller you are instantiating, and use that to control the tableView data, colours, etc.,
One way to start is with an enumeration to identify your different cases - and you can use these constants for the segue identifiers and to keep track of each instance of the presentation View Controller
enum ViewControllerType : String
{
case controllerType1 = "Controller1"
case controllerType2 = "Controller2"
case controllerType3 = "Controller3"
case controllerType4 = "Controller4"
case controllerType5 = "Controller5"
}
Then, make use of the prepare(forSegue
method
override func prepare(for segue: UIStoryboardSegue, sender: Any?)
{
switch segue.identifier!
{
case ViewControllerType.controllerType1.rawValue:
// standard definition
let presentationVC : GenericViewController = segue.destination as! GenericViewController
presentationVC.viewID = .dayView = ViewControllerType.controllerType1.rawValue
presentationVC.delegate = self
// specific to this controller
presentationVC.dataSource = dataSourceUsedForType1
case ViewControllerType.controllerType2.rawValue:
// standard definition
let presentationVC : GenericViewController = segue.destination as! GenericViewController
presentationVC.viewID = .dayView = ViewControllerType.controllerType2.rawValue
presentationVC.delegate = self
// specific to this controller
presentationVC.dataSource = dataSourceUsedForType2
// and so on for all cases ...
default:
break
}
}
This now means that you will instantiate a presentation view controller which has a variable viewID
which can be used to make type-specific changes to colours, etc., and which has the correct data source defined for the UITableView
then modify your presentation class to have something like this
class GenericViewController: UIViewController
{
var viewID : String = ""
override func viewDidLoad()
{
super.viewDidLoad()
switch viewID {
case ViewControllerType.controllerType1.rawValue:
// make specific changes to the view and data source here
break
case ViewControllerType.controllerType2.rawValue:
// make specific changes to the view and data source here
break
// and so on for all cases ...
default:
// handle default behaviour
break
}
}
}
Anywhere in the presentation view controller where you need to do something specific to the type, just include a switch based on viewID