What is the best practice to control multiple views? - ios

I have this view in the storyboard:
as you can see there are some fixed controls, and others that change according to the type of screen.
What do you think is better?
1- Same view controller for multiple screens. (more code to control views)
2- Add all controls in the same screen, then hiding and showing them by code? (messy code)
3- View controller for each screen. (replicated code)

Don't use the word "window", which can lead to different interpretations of what you are trying to say. Use the word "screen", or "section of the screen". In this case, I would use a container of UIViewControllers. To communicate between then, use KVO or NSNotificationCenter (most probably the second one). Also make sure to not have the data source directly on the UIViewController (like an array or a dictionary). Keep the Data Source somewhere else, where all the UIViewControllers (or any class) can easily access. You could go with a Singleton.
Putting the Data Source away, and not directly on the UIViewController, gives you more flexibility over your code. If you ever need to use a new UIViewController, nothing is changed, he can still request resources from the same point. So keep that in mind.
Edit 1
The data source also is inside the view controller, there is no
interaction between screens, it's the same screen but some controls
changes according to the type of it, what do you think I have to do
now?
The problem with this kind of approach is that if you need, for some reason to add a new UIViewController, that also use the same data source, what do you do now? I always try to decouple as much as possible the UIViewController from the Data Source. Otherwise you might have problems in the future, if the application changes (client's needs change). Again, moving the Data Source to a proper class, and use a Singleton to access it.
UIViewController <=> Singleton <=> Data Source
So now you suggest to make multiple view controllers with multiple screens?
I suggest a UIViewController to act as a container for the others UIViewControllers. For me it makes more sense to compose the Screen as I go, than doing everything in one place.

I'd definitly go with no 3. This approach is most flexible! And it is clean => good to maintain

Related

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

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.

Storyboard design pattern (to share or not to share)

This is probably largely preferential but I'd like to know if there are any reasons to decide one way or another on this.
When designing with storyboards you invariably end up with a number of view controllers. I'm looking at the overhead of a strict MVC approach where each controller is implemented in its own UIViewController subclass with corresponding UIView subclass (and even view model class for MVVM), and that seems to get out of hand quickly – it takes no time to add dozens of files to the project (many with little function). An alternative approach would be to link all the views to a common controller representative of all of the storyboard functionality.
My inclination is that if you don't have substantial controller code for any individual view controller, then the combination of all of them into one shouldn't be of harm to the readability of the code (and may enhance it over adding a large number of source files). On the other hand, if you have significant functionality to implement for any particular view controller, then it should be encapsulated within it's own controller.
In most situations I'd build all controllers to be as reusable as possible (encapsulated in their own custom UIViewController subclasses). Storyboards put this in an interesting light though since they seem to be geared towards sequences of views that typically have few entry points.
Your thinking is correct
If you don't have much functionality in each VC (ViewController) them combine all your code into one VC. The only drawback to this approach is that you won't be able to implement view specific code and every view where you will use this common VC will execute the same code whether its needed there or not. e.g. code in viewWillAppear etc.
Similarly if you have a lot of functionality for a particular view then its better to put it under its own VC
This is just a suggestion, if you need to use some common code logic between multiple VCs then instead of doing copy and paste in each VC of the same code, make it into a method of type Category and then call it where ever its needed. So change the code only at 1 place.
More VCs doesn't necessarily mean bad design. In my opinion its easier to maintain that way. My two cents. :-)
Each scene in your storyboard should have its own UIViewController subclass. Even doing it like this it's way too easy to get huge unmaintainable view controllers (MVC = Massive View Controller). Putting all the code for multiple scenes in the same view controller would create even bigger ones and also violate the Single Responsibility Principle. Each class should do only a single thing.
That also means you shouldn't duplicate the common functionality into all your UIViewController subclasses. Then they again would do multiple things - the common stuff and their actual purpose. Instead you can put your common code in other controller objects (which are not descendants of UIViewController) and use them in your view controllers.
Depending on the usecase a common base class would work as well, but it's always preferable to use composition instead of inheritance.
Another nice thing about other controller objects is that you also can add them directly in Interface Builder and connect actions and outlets to them. Your main view controller class often doesn't even have to know they exist.

How can I clone a UITableView from one controller to another so it stays in synch?

I found this in SO; it doesn't exactly answer my question, which is: is there a way to clone a UITableView from one controller to another while using Storyboards and maintain synchronization?
You can clone them in the sense that their initial property values remain the same, like position, layout etc. For this, just copy the UITableView from storyboard, go to destination view controller and paste it there.
If you share same UITableView object between two view controllers, it is still possible, but you must estimate how much work you would have to do yourself. When a view controller solely handles a table view, much of the work is done under the hood and table is handed over to you. In case of your UITableView shared between two view controllers, you would have to play with it quite carefully. You need to take care of entire life cycle of the view - see the usual methods like viewDidLoad, viewDidAppear and so on. How would you take care of them when your view exists in two scenes? Maybe you would be inventing a unique design pattern - if at all you find the most optimistic and programmatically correct way to accomplish it.
With storyboards, you cannot achieve cloning up to the level wherein data changes will reflect seamlessly between the two. Storyboard is, as the name suggest, just a board, where you can draw things to know how would they look initially, before your code takes over.
In order to achieve what you want, you have to create a shared model that updates two table views through proper delegate methods. Most likely such a model (NSArray, or any such collections as per your requirement) can reside inside a shared class (app delegate isn't a wrong choice), from where both your view controllers can refer to it. That is neat practice, it not only is right from programming perspective but also extensible and helpful to anyone who deals with the code any time.
For details about how to update UI from your model, there is nothing better than starting from scratch, going through the books I mean.
I am not aware of such possibilities.
I would pass the tableview source object amongst different controllers and let the view controller handle their own table view.
I think the best approach would be to use a framework such as the freely available Sensible TableView, then use the same model for both table views. This should be really straight forward.

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