How should one cope with multiple delegates in a paged UIScrollView - ios

I have a UIScrollView, contains 3 pages.
The first two are UITableView, the third one is a UICollectionView
So in one View Controller I will have to write delegate methods for all of them.
I googled a bit and found a solution like this (not tested yet),
Place each page in a separate UIViewController, implement the
corresponding delegate methods, and use UIViewController.view
attribute to build the scroll view
The UIViewController.view approach seems wrong to me, is that the normal way to do it?

Why are you trying to handle all the delegate calls in one view controller, can't you create separate view controller for each of them? If you are not separating now then it will be tougher for you to manage code later.

Absolutely using controller composition is a standard and respected solution to the Massive View Controller problem. Examine for instance the expositions at the StackViewController project which cleverly uses that concept to create forms in a UIStackView:
Composition over inheritance is a fundamental principle of object-oriented programming.
This principle has always been used in iOS view hierarchies, where more complex views are composed out of simpler ones (e.g. how a UIButton contains a UILabel and a UIImageView that render its content). However, there was no "official" way to compose view controllers until the introduction of view controller containment in iOS 5. It was possible to mimic behaviour like this prior to iOS 5, but handling the propagation of events between parent and child view controllers and transitions between child view controllers was difficult to get right, which are all problems that the view controller containment API solves.
In the same way that you can create complex layouts by composing multiple UIStackView instances, you can use the view controller containment API to compose multiple instances of StackViewController to create a hierarchy of view controllers where each content view is backed by a corresponding view controller that cleanly separates the responsibilities, instead of handling all of that at the view level (an anti-pattern, as mentioned earlier).
Also review 8 Patterns to Help You Destroy Massive View Controller, particularly
Standard Composition
View controllers can be composed using the View Controller Containment APIs introduced in iOS 5. If your view controller is composed of several logical units that could each be their own view controller, consider using Composition to break them apart. A practical application of this litmus test is a screen with multiple table views or collection views.
Which is, in fact, the exact situation that you have to practically apply it to!

Related

MVC: Is a custom UITableViewCell a view or controller or both?

I used to consider a CustomUITableViewCell.xib as the view and the corresponding CustomUITableViewCell.swift class as the controller of a table view cell.
Is this correct? A youtube video I stumbled upon considers the class as the view: https://youtu.be/n06RE9A_8Ks?t=177
Edit:
To clarify the question: Which one of the following is the view and controller? Are both considered the view?
CustomUITableViewCell.xib
CustomUITableViewCell.swift
I'd absolutely consider it a "view" (in terms of MVC). It's of the group of logic that (along with the .xib) handles 1 particular view of information, rather than orchestrating some aspect of the general logic of the app.
I also consider a UIViewController as belonging to the "view" part of MVC for the same reason. Of course, if you put far more business logic into your view controllers than that which is necessary to support the single view, then your view controller is some mix of MVC. For example, if your view controller chooses what scene of the app comes next, your view controller then participates in controller logic and it's not really following MVC. Your view controller is forced to do a lot of single view-related work, though, because there's a single view it's responsible for and that the view-work is more practically done in the UIViewController rather than the UIView.
So when you ask about a cell view class's stance in MVC, if it's doing single view work, then it's a "View". If you mix in controller work or model work, then you've muddied up the separation of responsibilities that MVC espouses.
In my personal opinion it is a view. It should be handling only UI components in the class. Think of both files as a complete view. One cannot be without the other. Thus I consider them one.

When to use Container View Controller ? and does it have any advantages in memory management over normal views in ios

When to use ContainerViewController? and does it have any advantages in memory management over normal views in iOS? In my application one of the screen is having two separate options which is responsible for different tasks. Should I use two ContainerView instead of two separate views. Which option will be more scalable?
Container views and parent/child view controllers don't have a meaningful impact on memory. You would need to have hundreds of view controllers in memory at once before different view structures would have a meaningful impact on your memory use.
Container views and parent/child view controllers are useful as a design pattern. It makes it straightforward to create discrete "tiles" of user interface where the views and the control logic that control them are one drop-in unit. Using parent/child view controllers is also the only way to make UITableViewControllers and UICollectionViewControllers useful, since those view controllers don't allow any other subviews in their view hierarchy.
From performance or memory management perspective it will always be equal or better to use UIView directly. From scalability it simply depends on what you are building.
A content view from storyboard is just a convenience. In general you can add any view controller as a child to another view controller by calling appropriate methods and adding the view as a subview. What you gain here is that your view controller will receive events that are specific for it while view itself will not.
In general view controller is just a wrapper around UIView. Application is designed so you need a root one but after that you might as well do everything with views alone.
Containers are used internally a lot. In reality view controllers may only present and dismiss. What you see as push, pop, set view controllers are all just using containers. Navigation controller consists of header and container view. Tab bar view controller has tab bar view and container view... Using containers you can easily create your own similar components.
When you use containers you will have a very clean code as you separate logic of each unit to its view controller. But at the same time your code may complicate because you now have trouble communicating between your view controllers. Imagine you have two parts of the screen where each represents a set of objects for a common model. Now it all goes well when there is no correlation between the two; but when first view controller changes an option which now needs to reflect in the second view controller you may need to report to delegate which is a parent view controller which will now report to the other child view controller. And even parent may have ugly code to access it's children. But on the other hand some MVVM procedure may handle this situation very nicely.
Anyway there are no apparent advantages or drawbacks. It depends on what architecture you will use and how you will use it. Both procedures are solvable and both can get ugly.

Is it better to have a viewDidLoad in all view controllers or just in the main view controller have multiple UIViews?

For now I have a single login view controller that hide and adds subviews dynamically based on user interaction. Is it better to have multiple UIViews with one view controller, or multiple view controllers?
The benefit of having children UIViewControllers would be if you needed to care about the view lifecycle in any of the children. For instance, if in some of your subviews (child views) you needed to know if it appeared to trigger some logic, then it would be good to use children UIViewControllers.
Another reason might be, if you wanted to use view controller transitions within your custom container, as described by Apple in the UIViewController class reference:
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/index.html#//apple_ref/occ/instm/UIViewController/transitionFromViewController:toViewController:duration:options:animations:completion:
But, to me it doesn't sound like you would need this, it sounds like you would just show/hide your views, or otherwise animate them.
But if your views don't care about any of that, and just need to render UI elements, I'd say using children UIViewControllers adds additional complexity without much benefit.
This is under the assumption that either way, all your views are living on the single UIViewController's view. If you are pushing and popping view controllers inside a UINavigationController, or presenting ViewControllers modally, you definitely should use UIViewControllers for that.
Also, you definitely shouldn't put all your view code inside that single view controller. You should use subclasses of UIView, or some other mechanism of making sure you separate your components.
For example you might have:
LoginViewController - organizes and hides and shows the individual views
SignInView - shows the sign in form
RegisterView - shows the register form
...etc
Of course its better to have multiple view controllers for many reasons:
Each view controller has its own code/logic/functionality.
Better for memory management. Once you're done from a view controller, system will automatically deallocates it from memory. Using multiple views will be overload in your system when some views are not used.
Better organisation for your project. You will just present/dismiss/push/pop view controllers and pass data between each other. Instead you will deal with horrible logic for hiding and showing UIViews.
Using one view controller will have a massive amount of code which in long term the project will be an impossible mission to manage.
Having multiple view controllers is better in the sense that you would have more ease at coding them individually. Also Navigation will be good which is good for User Experience.
Memory Management will be efficient.
The MVC architecture(Model View Controller) will instead become Massive View Controller which will be a headache while debugging.
Check out this answer for more clarity. I think you are confused between ViewController and View.
Check out the accepted answer of this question in the link. Hope it helps.
About viewController's "viewDidLoad" and "viewWillAppear" methods

Proper use of IBOutlets in Storyboard using MVC design pattern

Following the MVC design pattern for iOS apps using Storyboards in Xcode, I noticed that I can place IBOutlets for UILabels, UIImageViews, etc., into the ViewController or into the UIView itself.
Scenario 1:
Model Classes -> View Controllers (IBOutlets) -> UIViews in Storyboard Scene
the ViewController (VC) grabs the necessary data from the Model
IBOutlets in the VC are used to set the text and images that are in various UIViews in the Storyboard
Scenario 2:
Model Classes -> View Controllers -> UIViews in Storyboard (IBOutlets)
the VC grabs the data from the Model
the VC calls methods in each UIView subclass
those methods in each UIView subclass set the text and images in the associated UIView via the IBOutlets in that UIView
I found that Scenario 2 is more manageable when you have many UIViews and UILabels and UIImageViews in each view. The other approach can lead to a lot of IBOutlets in a single View Controller.
Which approach is best to follow when using Storyboards?
Your observation is correct, the second scenario leads to a more manageable design.
The difference between your two scenarios is primarily in their use of encapsulation: the first scenario encapsulates on the level of View+View Controller, letting the controller freely access things that should logically be part of the view alone, while the second scenario properly restricts access of IBOutlets to the view class, forcing the view controller to interact with them through the methods that you expose in your view.
As the consequence, the first scenario creates tight coupling between the view and its controller, while the second scenario significantly reduces this coupling.
Of course there is a tradeoff: you pay for reduced coupling with more code. Up to a certain point, it does not matter: when your views and their controllers are relatively small, it is easy to manage the combination of the view and its associated view controller as a monolithic object. The benefits of using the second scenario become more visible as the complexity of your views increases. This applies to all uses of encapsulation, not only to MVS in iOS scenario: the bigger your project - the more payoff you get from using proper encapsulation.

iOS - UIViewControllers sharing a screen

I'm writing an app that has two sections like this:
The idea is that on the top half I'm creating a request, and on the bottom I'm displaying the results. As my UIViewController subclass grows and grows I thought it might be a good idea to split that into two UIViewControllers. (So what I'm trying to do is something like a UISplitViewController).
Although I know it's possible programmatically I'd like to put both UIViewControllers in the screen from the Interface Builder so I can manage autolayouts and design there. Dragging and dropping doesn't work there.
Is that possible? And more important - is that a good design or should I stick to the rule "One view controller for one screen"?
You can use a custom container view controller to achieve what you want. See:
WWDC 2011 #102 on UIViewController Containment (Apple developer ID required)
the containment section of the View Controller Programming Guide
the containment section of the UIViewController Reference document
In short, since iOS 5, you no longer have to have a single view controller. Just make sure you call the necessary containment related calls. And iOS 6 makes it easier to design the storyboards for custom containers with the "container view" object.
Apple have stated (WWDC 2012, Evolution of View Controllers, I think) that the "screenful" is no longer appropriate. A view controller should manage a self-contained chunk of functionality.
As of iOS5 you can compose an interface of multiple view controllers using view controller containment (addChildViewController: and so forth). As of iOS6 you can do this in interface builder using containers and containment segues.
You will of course need a view controller to hold your two child view controllers - this will hold a screenful of content, and will usually perform any coordination between the two children.

Resources