What is proper MVC structure for embedding a custom view within another view? - ios

Thinking it over, this feels like a bit of a noob MVC question, but I can't come up with or find a definitive answer so I feel I should ask and get some clarity for myself.
I have a custom view that I created using a xib. It is going to be used in, currently, 4 other places in my app. Each usage has identical functionality, so I'm basically just creating a custom control object that I can reuse multiple times.
My "control object" consists of a UITextField, and two UIButtons.
The functionality I'm looking at implementing is, the first button will bring up a UIPicker and the 2nd button is essentially a done button and will just resignFirstResponder on the UITextField. As previously mentioned, this is consistent everywhere this will be used.
What I'm curious about is, is it ok for me to build this functionality directly into the custom UIView subclass since it is consistent behaviour for all instances of my control object? Or, do I need to create a custom UIViewController subclass to go along with it?
Currently, in my main UIViewController for my app I am creating instances of my custom UIView "control object" and treating them the same as any other control object. If I should actually be creating a custom UIViewController class to go along with it, well, I'll have more questions for another thread as to how I should be doing that (unless someone can direct me to a resource on this)
So far, searching the web has yielded nothing for me and from everything I've seen so far with iOS development in general, I've gotten the vibe that UIViewControllers are really only ever for a main, presentable view (that takes up the entire screen.. I might be missing some terminology for this).
My gut feeling is that no view controller is necessary in the scenario I'm describing, but I'd like to try to get some sort of confirmation, if possible.

There is no silver bullet, so no approach is absolutely right or absolutely wrong. What you describe here is just a view that changes its states. So putting everything in your UIView subclass is completely OK. It also conforms to the KISS principle.
However, as far as I understand, and correct me if I'm wrong, the input of your custom view - the text and the picked value from the picker does not really affects the view itself, but the viewController it's attached to. So you need to pass that input to the hosting viewController. This can be achieved by protocol with a default implementation. So the handling of the input data is written only once, but can be attached to whatever viewController you want.

Based off of everything that you've said, I see no need for another view controller. I can see where the answer could be a little unclear considering that the actions are something that ViewControllers usually handle, but I think you'll be just fine letting your custom view handle this by itself.
If you add more functionality or more complex operations, then perhaps it is time to explore other options but for now I think the single view will be fine.

Related

When following MVC design pattern what code should be in the UIViewController class file? - Swift4

I'm trying to understand how to properly implement MVC in swift. Heres my scenario:
I have a signup page with 9 UITextFields, and they're all being made programmatically, and therefore being anchored to the view programmatically. As you can imagine this would be a lot of repetitive code to have in the SignupViewController class file.
Is the convention when following MVC to keep the setup of these text fields in the SignupViewController file, or are you supposed to have a separate file such as SignupView that contains all the text field setup code?
Even though UIViewController has the word "controller" in it, I believe the majority of iOS devs these days assign the UIViewController to the "View" side of MVC. The UIViewController is chiefly specific to a particular view only, plus may manage its subviews as well (until this gets too messy and a container view is added to allow for a nested UIViewController).
In MVC on iOS, the view controller can easily become polluted with business logic, model management, etc... which is why many people jokingly refer to "MVC" in iOS as "Massive View Controller". To combat this, consider using an MVVM architecture instead, which not only keeps the VCs small, but also moves the business logic out to a separate "sidecar" coupled to that ViewController, called a ViewModel. This allows the business logic to be unit tested without any UI involved, making testing much more reliable and easier to read and maintain. With that said, the creation of these 9 controls would still belong in the ViewController.
As for programmatically adding UITextFields to your view vs viewController, if this is to be done just for this single scene, then I'd stick it into the viewController. If you expect to want to reuse the set of them in other scenes, then making a custom view or control containing them would be better, like is typically done for custom cells of a table.
Finally, consider simply using a Nib or Storyboard to layout your scene. Apple has provided so much power to layout and maintain scenes via nibs and storyboards that you're really missing out to go the programmatic route. I find it very rare that I side with programmatic approach. The auto-layout warnings in InterfaceBuilder alone are worth gold to me, and as Apple continues to raise the bar and change layout rules, I can't imagine trying to keep up programmatically when I can't afford to test every device and iOS version combination. And yes, it's possible to do MVVM with dependency injection and storyboards. I do it daily.
Answer to your question is that it has nothing to do with MVC .
AS iOS/Mac developers, we use Interface builder and auto_layout to achieve most UI #IBOUtlet/ #IBAction. This is the V side of MVC.
Typically, If you have data, database, json or whatever formats, you need to model them and handle logics. That'M of MVC.
The C(Controller) side of MVC is a kind of glue between M and V. In most cases of mobile , you can think Controllers are all C you need.
So controller class is the only portion you need to put code to simplify everything.
In your case, 9 UITextfields should be ideally put into V side job. Please don't write code for them unless there is no better way to do.
I don't agree with above statement about using Interface Builder... I prefer to write most of my views in code and also set the anchors that way as well.
to minimize the file you can create an extension of the ViewController in a separate file to contain all of this code.
so for SignupViewController you would create a new file called SignupViewController+SetupUI.swift.
import UIKit
extension SignupViewController {
// add your setup methods here
// as just an FYI you can call the methods you create from your
// SignupViewController file just like you would any other method.
}
you can read more about extensions here.
After reading about good practices to write maintainable and readable code you should do the whole design in interface builder. If you get good understanding of constraints you don't need to write any code to setup design in your view controller. The ViewController.swift file should not be used to fetch-handle data or to setup the UI. It should just be responsible to display and update values which are fetched and get handled in a separate ViewControllerDatasource.swift file. So to sum up, view controller does not have any logic implemented it just handles the show data and the design updates(not setup). I hope i helped you with your question.

What is the design pattern being used in this video?

I recently watched this video tutorial on how to create a custom UIPickerView, and I successfully implemented the UIPickerView in my project. However, I would like to make some changes to the UIPickerView that appears within my app.
For starters, is the custom UIPickerView outlined in the video an example of subclassing?
Second, is it possible to modify an instace of the custom UIPickerView to have a different text label other than Done? And if so, would I have to modify the KCModalPicker.h/m files?
Thus bringing me to my third question, if I modify the KCModalPicker.h/m files then every other instance of the class in my project will inheret the changes, so what is a way to keep the base class as is, but be able to add customization to the class, so things like how many columns the UIPickerView has is dependant upon the instance that is obstantiated, and not dependant upon the KCModalPicker.h/m files?
UPDATE
The source for the ModalPicker class I am referring to, can be found here,
https://github.com/subdigital/nsscreencast/tree/master/025-custom-picker-component-part-1
I don't want to watch a video in order to answer your question, and suspect others feel the same way. (I hate watching development videos because they are long and tedious. I don't need somebody explaining in great and painful detail how to do something. Let me skip to the parts I'm interested in.) You should describe the scheme that is used so that we can answer your questions about it.
If that video describes a class KCModalPicker, it might subclass UIPickerView, or it might contain a picker view (that would be a "has-a" relationship, not an "is-a" relationship. The KCModalPicker is probably a modal view controller that has a picker view inside it.)
If you want to modify a class, like KCModalPicker, but don't want to change all instances, then yes, subclassing would probably be a good way to go. Create a subclass called something like MyModalPicker that inherits from KCModalPicker and changes the behavior however you need it to.
EDIT:
After looking at the files on Github, it looks like the project has a class BSModalPickerView which is a subclass of UIView, and contains a UIPickerView. As described above, this is a "has-a" relationship. The BSModalPickerView class has a picker view inside it that it manages. So no, this project does not appear to use subclassing.
The demo program has a view controller that uses the BSModalPickerView method presentInView:withBlock: that displays the picker as a subview of the view controller's main view.
It looks like there is also a method presentInWindowWithBlock: that will display the picker view directly in the window.
If you want to modify the behavior of some BSModalPickerViews and leave others alone, creating your own custom subclass of BSModalPickerView would be a reasonable way to do that. You could also modify the root BSModalPickerView to have more setup options (extra properties or parameters that you pass in the init method).
BTW, your question asks about KCModalPicker.h, but the class I see in the github link you posted is BSModalPickerView. Not sure what the discrepancy is.

iOS -- When to create a child ViewController vs. a UIView Subclass?

Maybe this is a silly question, but I've bumped into it a number of times during iOS Development.
Sometimes I'll develop a view component that I want to use on multiple screens, so I'll decide to subclass UIView and make it something I can use in multiple places.
Then, I start adding functionality to it. Maybe it needs to respond to an NSNotification, or it is supposed to respond to user touches.
At a certain point, I start wondering if I should really be making a UIViewController subclass, and add it to my UI as a child ViewController.
Is there any consensus on where to draw the line between adding some behaviors to a UIView, and when to create a full UIViewController?
I can't tell you about the consensus, but here's my opinion:
Subclass UIView only when...
You want to do custom drawing
You need to customize some behaviour of an already existing UIView subclass
You have special needs for layouting subviews. Most layouting can be done by UIViewController, though.
Maybe for special touch handling that you can't be done with gesture recognizers
Subclass UIViewController in all other cases. You almost always need a controller anyway, for writing glue code that ties together views and models, or for handling user interaction. Consequently, Apple has made it easy in UIKit to let controllers do all the work and to keep views as "stupid" as possible. For instance, it is very simple to nest controllers to create complex view hierarchies, without the need to have a single view subclass.
An indicator that subclassing UIView is not the first thing one should do is the section titled "Alternatives to Subclassing" in the UIView class reference. An indicator that subclassing UIViewController is the preferred thing to do is that there is no such section in the UIViewController class reference :-)
You should use a controller anytime that you need to handle or control data. Views are supposed to be as stupid as possible, not knowing what they are displaying but rather where. You can easily subclass and reuse ViewControllers. A good example, say you need to retrieve a string (or text) from the user throughout your app via a popover controller and a modal. Create a generic subclass of UIViewController that has a view with a textfield and a button. You can then use this view and it's controller in any capacity you need. Reusing it in the popover, modal or anywhere else (and generally passing the data back through delegation). Since you are dealing with data you should not being using a sole subclass of UIView.
From my experience I subclass UIViewControllers more often then UIViews. It is a little difficult for me to understand if you are solely talking about Containers or reuse of views in general application workflow. Either way though it should be the same.
I've used the embedded view controllers to load reusable table views from time to time. I've found that it's useful sometimes but not always. Communication between the two can be cumbersome, like if you want the embedded controller to communicate back up to the container. Delegation makes it easier but still cumbersome. It also limits you to iOS 6, if I remember right iOS 5 and lower don't support embedded controllers.
If it's just adding methods you can use a category to store some extra methods. I do that a lot on NSManagedObjects that I don't want to subclass and if I regenerate the NSManagedObject from the datamodel I don't lose the code in my categories. Gives me added functionality like calculated fields or conversion methods without having to subclass. If you don't need those methods for a particular instance just exclude the reference to the category.
Subclassing never is bad though IMO.

Pattern for class to manage view controller flow

At the moment I'm using a Singleton class to do some work but I'm wondering if there is something better.
I have an app that has a completely dynamic work flow. It uses a navigation controller but the order of the view controllers depends entirely on some data that is downloaded from our server.
The entire workflow is downloaded and saved in an array.
The "main menu" screen of the app has several choices (settings, recent, etc...) these are fixed but one of them is the dynamic one. It always starts with the same type of view controller but from then on it depends on what you choose.
Description
There are 4 different types of these dynamic controllers.
Table View Controller with single selection and detail indicators.
Table View Controller with multiple selection and checkmarks.
View Controller with a text field and keyboard.
View Controller (with other related VCs) used for searching for accounts on the server.
When you press the option "New Event" on the main menu the menu then goes off to the singleton (EventManager) and tells it to start a new event.
The singleton then pushes a single selection dynamic view on the nav controller and gives it the initial options.
From here on the singleton picks up all the selections and works out what type of view is required next.
I hope this is making sense
Anyway, I don't like the singleton pattern here as I don't think it should be a singleton.
What I would like is a class that I can create from a ViewController and this class will then control the pushing and popping and flow of data between a load of different view controllers. Then when you go back to the main menu this class can go away so I create a new class each time.
Is there a pattern that I can look at that will do this? Or should I stick with a singleton like I am now?
I hope this makes sense.
EDIT
Could I use a UIPageViewController for this? Then the datasource/delegate object of the UIPageViewController will take the place of the Singleton I am currently using... or something?
ADDING PHOTO FROM TWITTER REQUEST
Each VC along the flow has no idea what cam before it or what comes next. All they do is call back to the singleton to say "This value was selected" or "This text was entered" etc...
The singleton then stores that info and works out what comes next and pushes the next VC onto the stack.
It needs to be able to move back along the stack so the user can go back to change something etc...
It's all working as it is I just don't like the use of the singleton.
Lots of comments here in order of importance.
Everything you've described here sounds really good, even down to the naming. "EventManager" sort of sounds like it manages all "events" in the system (so I'd expect there to be a class called Event, but that's a tiny quibble and the name is likely still very good). There are other good designs, but I wouldn't have any problem with yours.
I agree that this does look like a good fit for UIPageViewController. You should certainly investigate that to see if it's the right fit. It's always nice to use a built-in controller if you can.
There's no reason to strongly avoid singletons. They are a natural part of iOS development and fairly common in good Cocoa design. They should be "shared" singletons generally (never create "strict" singletons that override +allocWithZone:). This just creates an easy-to-access instance rather than a true "singleton." This is the way things like NSNotificationCenter work and is often a very good pattern.
Singletons are best when many random pieces of the system need to access them directly and passing them around to everyone would be a lot of overhead (especially if many of the pieces you'd have to pass the object to don't need it themselves). Again, think NSNotificationCenter. If the users of it are mostly contiguous (i.e. most objects you would pass it to actually need it themselves), then just create one at the start of the program and pass it around. That sounds like your situation, so your intuition about it seems good. Just de-singleton it and pass it. Easy change.
But I'd definitely dig into UIPageViewController. It could match your problem very well.

Trouble understanding viewControllers in iOS

I'm new to obj-c/iOS and I'm having trouble understanding conceptually at least viewControllers. I've read a lot of the Apple Doc's, I've even used viewControllers to some extent in xCode, but I still don't quite get what they are, or what are the best ways to use them.
I've been an AS3 dev for many years so my mind works in the context of MovieClips/Sprites and the Display list to get graphics on the screen.
Ok so from my understanding...
A viewController is a kind of class that handles graphics in some
fashion and then allows you to do something with them?? What is it in it's most basic sense?
You seem to add viewControllers to a Window class, which I guess is a bit like
adding a display Object to the Display list?
What is it that a viewController does for you in it's most basic sense?
Are there certain things you definitely can't do with them or shouldn't do
with them?
Do viewControllers need to be connected in some way to the rest of the iOS framework to function (apart from being added to a window).
How exactly do they use data? (I've read up on MVC, I understand that conceptually this is a slightly different question) as I understand it you don't hardcode data into a viewController, so how does a viewController access any static data?
Let's say I just wanted to throw an image up on the screen, exactly what part would the viewController play in that process? is it just something which handles only one small aspect of that process or is it the whole show and handles everything?
Does one viewController handle multiple images? is it like it's term, a "controller" for all the images presented on screen, or does it handle one image at a time?
What is a viewControllers connection to the image(s) it handles? it contains references to them?
I'm using the Sparrow framework which is helping but I would still like to be able to get my head around what viewControllers are so I know how to use them properly.
Ha, I apologise for the above I know it must look like I'm completely confused :) thanks for any advice.
Hope this helps you:
A viewController is a kind of class that handles graphics in some fashion and then allows you to do something with them??
It's the glue between a View (Xib File) and the Data (Could be
CoreData or whatever you're using in the backend). All the UI Elements
you are using in the View you normally define as properties in the
controller to get access to them.
What is it in it's most basic sense?
You seem to add viewControllers to a Window class, which I guess is a bit like adding a display Object to the Display list?
I don't really know AS3 so I cannot compare Display lists with ViewControllers. But basically ViewControllers are there to handle
different types of transitions between the views and accessing
(setting/reading) the data which is displayed in the view.
What is it that a viewController does for you in it's most basic sense?
Like I've written above. Most basic sense they interpret what the user
does on the view and depending on the action of the user changes the
model.
Are there certain things you definitely can't do with them or shouldn't do with them?
It is always hard to keep the border between model and controller.
They are pretty close to each other. So what I normally try is to
delocate all logic stuff (like calculations, database access and so
on) this does more belong into the model part. But of couse you're
using these external classes in the controller.
Do viewControllers need to be connected in some way to the rest of the iOS framework to function (apart from being added to a window).
Well like you already have written the ViewController needs to be
connected to a view. Otherwise it would not make much sense. There are
different subtypes of UIViewController such as UINavigationController
where you probably need to overwrite some other methods to provide the
whole functionality wanted by these special subtypes.
How exactly do they use data? (I've read up on MVC, I understand that conceptually this is a slightly different question) as I understand it you don't hardcode data into a viewController, so how does a viewController access any static data?
There could be different approaches to store the data. Simplest way
would be to have the data directly stored in the UIViewController.
This could be a custom class which is the container of the data. All
changes are directly written into this class and displayed by the
UIViewController. But in most of the cases it makes sense to use
CoreData (Which is responsible for reading/writing the data into a
sqlite database). You could look at CoreData as your model and the
UIViewController gets the data from there and passes the data which
the UIViewController has received from the View back to it.
Let's say I just wanted to throw an image up on the screen, exactly what part would the viewController play in that process? is it just something which handles only one small aspect of that process or is it the whole show and handles everything?
The UIViewController would store an internal Property (UIImageView *)
which is in the Interface Builder connected with the UIImageView you
have created in the Xib file. So over these property you can change
through your Controller the image.
Does one viewController handle multiple images? is it like it's term, a "controller" for all the images presented on screen, or does it handle one image at a time?
Yes, this isn't a big problem. You can have as many images you want.
You just need to have the properties defined in the UIViewController
and linked to the View.
What is a viewControllers connection to the image(s) it handles? it contains references to them?
Yeah, its like a reference to the UIElement. You can then change
whatever property of the UIImageView you want directly from the
UIViewController
Some useful links:
Apple Official ViewController Guide
Apple Official ViewController Basics
You should have a look at Storyboards (U can use them since IOS 5.0)
I recommend you to check:
https://stackoverflow.com/questions/1939/how-to-articles-for-iphone-development-and-objective-c
Here are the answers to your questions:
No, it's doesn't handle graphics. It's the controller of the MVC design pattern. It handles the lifecycle of it's contents (for instance the views) and the data linked with.
A UIViewController is set as a root of an UIWindow. For instance, a UINavigationController is a subclass of UIViewController that stacks UIViewController in order to deal with the navigation.
Response in (1)
Try to be more specific with this question please.
As already commented, it's useful if you use the already built-in components like UINavigationController or UITabBarController.
For instance, you can have the data in instance variables and the display them in the contained UIView.
The UIView attached to your UIViewController will contain an UIImageView. Your UIViewController would have a connection with it in order to whatever changes you need, for instance, changing the image when the user press a button.
It can contain multiple UIViewsand therefore multiple UIImageViews (it's a subclass of UIView)
As commented, they would be contained on an UIImageView and would be linked programmatically or with an IBOutlet.
In a nutshell, a view controller is the controller in the MVC pattern. Please check this link before reading further so you're up to date with this pattern:
http://developer.apple.com/library/mac/#documentation/General/Conceptual/DevPedia-CocoaCore/MVC.html
OK, basically a controller manages a collection of views. It also fetches data from your model and sets the state of the views. It's important to note that the views know nothing of your model (your data), and the model knows nothing about your views. A controller also receives events from the views and decides how to change your model accordingly. It is essentially managing the synchronisation between your views and model.
There are technologies that help automate this such as KVO and key value binding. A google search will help you there.
One more thing. No other part of your application should access your views except for the controller. So generally in an application controllers tend to communicate with each other, for example via transitions or the delegate patterns between controllers under a navigation controller. So your application backbone tends to be controllers talking to each other.

Resources