I am currently making up a directory structure, which is supposed to enable me to work clearer with the MVC model in my iOS-projects. I therefore created a folder for my Models, Views, Controllers and integrated APIs, but wonder where to put custom segues. I know that they do not belong to the API directory or to the model, but I would neither add them to the Controllers as segues do not coordinate the workflow and not to the Views as they are not visible or contained in a UIViewController. Are there any suggestions where to put the UIStoryboardSegue files? Thanks.
Since Segues are meant to perform transition between controller I would put it with the Controllers.
But note that iOS framework combines view and controller. This approach is called MVVM, hence the name ViewController. This means it will be tricky to treat it as pure MVC.
For instance what would be in the view?
Should it be storyboards, or custom view classes?
Related
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.
I'm trying to understand communication between two view controllers.
When passing data without segue, I saw two methods to create destination controller instance.
First one is storyboard?.instantiateViewController(withIdentifier:). Second one is ViewController(nibName:bundle:). Then present them with present(UIViewController..).
What are the differences between the two methods? Are they just to find view controllers by a storyboard identifier or a nibName?
instantiateViewController(withIdentifier) is for view controllers that are inside a storyboard, while UIViewController(nibName:bundle:) is for ones that were created in a .xib file. Both can be used, it just depends on the method the application was created.
If you are planning to make complex view controller relationships, storyboards might be the better solution for you, since view controller organization is more efficient when you can structure your VCs in a two-dimensional place.
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!
I am at the beginning of developing an iOS app I am having trouble understanding the MVC (Model-View-Controller) design pattern. I thought I had it down but the more I read the more confused I get. I don't know if this should be an iOS specific question or if the same goes for every use of MVC. I am not using storyboards btw, I want to do it all programmatically.
I believe I understand the basic relationship between Controllers and Models, it's the separation of Views and Controllers that I don't get. Let's say I want to create a UIButton and display it on the screen. Should I initiate the button in the Controller or the View? The controller is responsible for what should be displayed, correct? Wouldn't you just call on a View to display that and not worry about creating the button in the Controller? From what I understand, View Controllers are just Controllers and should therefore control the View, not be the View. It seems like most people do just about everything in the View Controllers. I guess my question boils down to what code goes where?
UIViewController is controller part in the MVC pattern of code.
M(Model)
C(ontroller)
V(View)
Controllers handle navigation between different views , etc.
From here you can get more idea : view and viewcontroller
A view is an object that is drawn to the screen. It may also contain other views (subviews) that are inside it and move with it. Views can get touch events and change their visual state in response. Views are dumb, and do not know about the structure of your application, and are simply told to display themselves in some state.
A view controller is not drawable to the screen directly, it manages a group of view objects. View controllers usually have a single view with many subviews. The view controller manages the state of these views. A view controller is smart, and has knowledge of your application's inner workings. It tells the dumb view objects what to do and how to show themselves.
A view controller is the glue between you overall application and the screen. It controls the views that it owns according to the logic of your application
About View Controllers
View controllers are a vital link between an app’s data and its visual appearance. Whenever an iOS app displays a user interface, the displayed content is managed by a view controller or a group of view controllers coordinating with each other. Therefore, view controllers provide the skeletal framework on which you build your apps.
iOS provides many built-in view controller classes to support standard user interface pieces, such as navigation and tab bars. As part of developing an app, you also implement one or more custom controllers to display the content specific to your app.
Not sure about any iOS specifics but from a PHP standpoint controllers are there to get any data that is needed for the view (via models) and then pass that data to the view.
The view is there to render things to the screen only and should have no logic in it.
So from a website point of view if you wanted to display a users name on the screen:
The controller would request the username from the model
The model would get the username and return it to the controller
The controller would then pass the username to the view
And the view would then render the username.
Hope that helps.
To be not specific, but on a upper layer, you can say as following :
You can put controller code in class extending UIViewControllers
You can put view code in class extending UIView
You can put model code in class extending NSObject
I come from an ASP.NET background so I'm not sure if there is a way to do this in iOS. Essentially, we have a design paradigm in our app where you can either have a single item in your model or multiple items. Depending on which one, different subviews are hidden/shown.
I have already created a custom subview that inherits from UIView which handles this with the help of a delegate to get some information from the ViewController. I have implemented it on multiple screens which works fine. However, the separate view controllers are duplicating a ton of code such as when to update the model, what to do when the model is updated, etc. Essentially, stuff that the view controller should do. It would be great to keep this code in one place as opposed to the different ViewControllers.
I know I can have my custom subview's class inherit from a UIViewController, but I also need the ability to have additional views above or below the reusable one. What are my options for this? In ASP.NET you can just create a user control which knows about the page lifecycle and can know about the model.
"I know I can have my custom subview's class inherit from a UIViewController" -- no, you can't do this. A view can't inherit from UIViewController, and in Apple's MVC paradigm, a view shouldn't know anything about the model. Without knowing more about what you're doing, I would say one thing you can do is to make a base view controller class that your other controllers inherit from to cut down on the amount of duplicated code. Since the controller mediates between the model and the view, you should have the controller tell the view which of its subviews to show or hide, based on the model.