Transitioning from the web-stack to iOS wonderland, I am finding it hard to understand how to re-structure my thoughts for MVC and effectively structure my UI on iOS.
What is the best way to think about composing views to my self.view
with:
UIView
classUIViewController
with an associated UIView
class. UIViewController
with inline UIView
------------------------------
| A |
| |
| -------------------- |
| | B | |
| | | |
| | -------------- | |
| | | C | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | | | | |
| | -------------- | |
| | | |
| -------------------- |
| |
------------------------------
A
might [self addView:B_view]
(If B was just UIView)A
might also [self addView:B_viewController.view]
(If B had a view controller)A
might also [B setChildView:C_view]
B_viewController.delegate = A
& C_viewController.delegate = A
B_viewController.delegate = A
& C_view.delegate = B
The logic is scattered across delegates, viewControllers and views.
Apart from the argument "abstract well and separation of concerns" that can improve above experiences. I believe its the bleeding of viewController and viewController.view being composed to easily cause extensive coupling.
This quickly becomes confusing and feels like spaghetti and hard to control despite efforts.
That said,
Perhaps, what you are dealing is with the MVC - Massive View Controllers dilemma. Here is an interesting read where Marcus speaks of managing code effectively by putting the code where it belongs, networking layer, persistence layer or the presentation layer(ideally the viewcontroller).
http://www.cimgf.com/2015/09/21/massive-view-controllers/
Apart from the delegation pattern we also have block/closure based approach that might help to clean up the code.
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html
In general, Robert C. Martin's clean code approach could be of help here. The way to implement it through something called as VIPER architecture. Here is a tutorial on that.
https://www.objc.io/issues/13-architecture/viper/
Objective C, as a language embraces the delegation pattern and it is a standard practice to use it for most of one's concerns.
Welcome to the iOS platform.
I failed at asking similarly broad questions at stackoverflow - seems like community favors more specific technical question. But I'll give it a shot. Keep in mind that all following are my opinions and not hard and fast rules.
I feel like it is a composite question about message passing and design patterns. In terms of components communication (whether they are views or controller) there are many ways to go about it, each has it's +
and -
(or rather use cases). There is: delegation, responder chain, blocks, notifications, reactive signal - just to name a few.
self.superview
or self.parentViewController
(some say even self.navigationController
) it probably violates encapsulation and there is a better way.Following are few random observations that might lead you somewhere (or might not).
In my opinion, MVC is a great pattern for small project (it is easy from "easy vs simple"). But from personal experience it quickly gets out of hands when the complexity of the screen you're working on grows. Tendency is for the controller to handle everything from user interaction to networking and it becomes a 1k-long monster really quick.
Sadly a lot in iOS architecture is relying on UIViewController
. Often it inevitably becomes a first point of contact of your code with OS, but it doesn't have to handle everything internally. Instead it can route responsibilities to appropriate components, i.e.
func loginButtonDidTap(_ sender: UIButton) {
loginManager.beginLogin(from: self)
analytics.reportLogin(with: sender)
// ...
}
I didn't quite notice from your description, but if you prefer to go with MVC it is a completely valid option to compose controllers. It is a very common situation when building for iPad but even on iPhone every screen can easily include completely independent pieces where every one of them is a separate ViewController
, then you should look into what's called "UIViewController containment". Mostly it allows for better separation and reuse, but again, doesn't solve the main issue.
If you are reading this, you are very eager to learn🙂 In this case, I'd suggest not to stop on MVC. There are many interesting design patterns that might or might not be suitable for your particular needs. MVVM was (is?) quite popular. Lately unidirectional flow seems to be the new hot thing. Inspired by JS's Redux. It is a very much departure from MVC and I suggest checking this project out https://github.com/ReSwift/ReSwift if you are interested.
Sadly like any architectural question there is no right and wrong - there are only things that work for you and your team or not. And I'd love to hear other perspectives before question gets closed as "too broad" 🙂
Sorry if this is completely not what you asked for, let me know if there are any particular aspects you'd like to discuss.
You can have one ViewController
Have UIViews separated to ViewController. It should not be tightly coupled with viewController.
Have your View login in UIView class itself. Create its own delegate and protocols. and use it in any viewcontroller.
add viewcontroller to viewcontroller is not a good solution.
You can also move to MVVM where every view will have its logic part in its View Model, But it can be confusing at beginning.
Try to make UIViews separated to ViewControllers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With