Reputation: 2539
I am struggling with the following issue:
I have a ViewController
and a separateUIView
attached to it which I use instead of storyboard or xib/nib, meaning I took the "drawing views programatically" approach.
class MyViewControllerA: UIViewController {
override func loadView() {
self.view = MyViewControllerAView()
}
}
The above works all fine.
Then within my MyViewControllerAView
I am using a third party UI component which loads two UIViewControllers
within the MyViewControllerA
by using a delegate:
class MachineHomeView: UIView, ThirdPartyUIComponentDelegate {
//code ...
func thirdPartyUIComponent(_ thirdPartyUIComponent: ThirdPartyUIComponent, viewControllerAt index: UInt) -> UIViewController {
switch index {
case 0:
return MyViewControllerC()
case 1:
return MyViewControllerC()
//..more code
}
}
}
And the UI looks like:
In a nutshell, I have a ViewControllerA
whose View
loads two additional ViewControllers - ViewControllerB
and ViewControllerC
As you see I am trying to follow the MVC approach by separating the View
and the Controller
from each other.
The problem I am facing is that I would like pass data from MyViewControllerA
to MyViewControllerB
and MyViewControllerC
.
The first thing that comes up to my mind is to create a property in the MyViewControllerAView
e.g callled test
. So in viewWillLoad
or viewDidLoad
I can pass stuff to it like:
self.view.test = "some data"
Then in the delegate where I instantiate the two additonal view controllers I can do:
func thirdPartyUIComponent(_ thirdPartyUIComponent: ThirdPartyUIComponent, viewControllerAt index: UInt) -> UIViewController {
switch index {
case 0:
let myViewControllerB = MyViewControllerB()
myViewControllerB.someProperty = self.test
return myViewControllerB
case 1:
let myViewControllerC = MyViewControllerC()
myViewControllerC.someProperty = self.test
return myViewControllerC
}
}
}
In my mind going the above way is breaking the MVC convention because the View is no longer UI responsible only. Therefore I want to avoid that and keep the MVC clean.
Any ideas of how pass data from MyViewControllerA
to MyViewControllerB
and MyViewControllerC
without breaking the MVC pattern or introducing a bad practice ?
Upvotes: 2
Views: 95
Reputation: 176
UView shouldn't create UIViewControllers and manage them itself. Make ViewControllerA responsible for managing ViewControllerB and ViewControllerC. Great way to do this is make B and C child view controllers of A. You can communicate with parent view controller A by delegate. Apple tutorial how to make this: https://developer.apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html
However @Milan solution is ok too.
Upvotes: 1
Reputation: 19737
I believe you should approach the problem in a following manner.
Move the thirdPartyUIComponent(_:)
method out of MyViewControllerAView
to the MyViewControllerA
- I don't think it's appropriate for the view in MVC to instantiate and handle view controllers. Now the MyViewControllerA
view controller would be responsible for view controllers B
and C
.
Then, since I expect that you need to access the views of B
and C
in the MyViewControllerAView
, pass them directly to the MyViewControllerAView
- however, pass only views of B
and C
, not the view controllers themselves.
This way the A
view controller will manage view controllers B
and C
, but the MyViewControllerAView
will still have access to the B.view
and C.view
to lay them out properly.
P.S.: If the thirdPartyUIComponent(_:)
callback should be called when some UI action is triggered by the user on the MyViewControllerAView
, then use the delegate pattern to pass that event to the MyViewControllerA
to handle it cleanly.
Upvotes: 2