What's the best controller to use for interactive books? - ios

I'm creating an interactive touch book in iOS. I'd like to know what the best controller is to use for books. (e.g. UIViewController, NavigationController, etc.). I'd prefer to stay with storyboard options.
And secondly what is the best way to handle pages? A separate ViewController for each page? a separate view for each page?

UIPageViewController
From the docs:
Page view controllers allow users to navigate between view controllers
using the specified transition. Navigation can be controlled by the
user using gestures as well as programatically.
View controllers are either provided one at a time (or two at a time,
depending upon the spine position and double-sided state) via the
setViewControllers:direction:animated:completion: method, or provided
as-needed by the data source. Gesture-based navigation is enabled only
when a data source is provided.
To alter the behavior of this class, you should provide a data source
and delegate. This class is not intended to be subclassed.
As for your second question, yes it is easiest to manage each page as a view controller since UIPageViewController is a container view controller and it holds an array of view controllers.

Related

How to create simple tableview and load data using Swift in iOS

I am trying to create an app for iOS using Swift but running into problems with the very basics.
To keep it simple I just want the app to initially be a single view application with a button and some sort of list view on the page. I believe a TableView is what is recommended here. When I click the button, I just want it to populate the list/table view with some entries, that's it. To start with, I don't care if these entries are hard-coded, I just want to get something working.
I have been looking at different samples but I am getting confused. Some of them seem to suggest using a TableViewController others don't. When I use a tableview controller, the UI I had created seems to get completely replaced with just an empty tableview list and the button is gone.
I previously have developed apps in Windows phone and found it a lot easier. I'd just add a listview object and in the click method of button, add the items programmatically etc. But this is my first time trying to create an iOS app and it seems a lot more confusing. There are delegates, controllers, views all seemingly needed in order to do something very simple.
Can anyone give me some basic step by step instructions about how to add a tableview to an application and load some data into it through a button click?
Make sure you are clear about the difference between a view and a view controller.
iOS uses the MVC design pattern (Model View Controller).
A view object displays contents to the user and responds to user interaction.
A model object stores state data.
A controller object drives the app logic and mediates between the model and the view.
A UITableViewController is a special subclass of a UIViewController who's job is to manage a table view. It has some extra support in it that makes it a good choice for managing a table view, BUT... there is one annoying thing about it. It is designed so the ONLY view it can manage is a table view. You can't use a UITableViewController if you want to add buttons, labels, and other UI elements to your screen outside of the table view.
What I usually do is to create a create a table view controller, create a separate regular view controller, add a container view to the regular view controller, and then use an embed segue to embed the table view controller inside the view controller. (you just control-drag from the container view to the table view controller.) That way you get the best of both worlds. You may want to create a protocol that the table view controller would use to communicate with it's parent view controller.
You should be able to find a tutorial online on setting up a table view controller as a child of another view controller using container views and embed segues. It's quite easy.

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

How to share controller amongst different iOS views

I am coming from a C# wpf background where you can have one ViewModel handling multiple Views. This is a great way to share data amongst unrelated views. However I can't figure out how to do the same thing in iOS, as you seem to need a Controller for each View.
What I am trying to achieve is to have a sign up sequence where the user populates 5 screens of data one by one. I was going to use a PageViewController for this and each click on Next would transfer them to the next page in the sequence. All the while, adding all their input data to a parent model object which stayed around for all five screens, at the end you can submit the whole lot to the database to sign up.
The only way I can see so far to do this is to create five separate ViewControllers, one for each screen of the sign up, and create the navigation logic to display them as you click through. However this a) seems overkill and b) means each subsequent screen and viewcontroller doesn't know about the information the user entered in the previous steps.
What is the correct way to do this in iOS?
You can do it in many ways. If you like to use UIPageViewController, you can actually have one view controller for all steps of the sign up process.
A main view controller would implement protocol UIPageViewControllerDataSource. It has two required methods, which return an instance of a content view controller. These instances can be of any UIViewController subclass, so you could have five separate view controller classes or you could have five instances of the same class.
Xcode has a project template "Page-Based Application". It might be a good sample code for you. There is one class DataViewController and it is instantiated for each page. If your case is really simple then this might be the best solution.
If you use multiple view controllers, you can pass data between them by overriding the method prepareForSegue(segue:sender:). The UIStoryboardSegue object has access to the destination view controller, you can cast it and set up the properties. (I am assuming you are using storyboards and segues.)
Another approach would be not to use UIPageViewController and implement the whole process within one view controller. There could be one view with five container subviews. Initially the first one would be shown, then the second one, and so on. This requires manual implementation of navigation between those steps, but gives a lot of flexibility. It's also more aligned with MVVM, because there is one-to-one mapping between a ViewModel and ViewController.
In general, iOS apps have lots of view controllers. It doesn't seem an overkill for me to use five in your case. It might be more code, but it's less complexity.

What should be in View Controllers and what should be in Views?

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

Please clear some confusions regarding UIViewController

Please clear some confusions regarding UIViewController
I found this article Abusing UIViewController and here are the links link1 & link2
and summarised points
This is author's (and Apple’s) advice In a nutshell:
One (and only one) view controller should be responsible for a whole hierarchy (or screenful) of UIViews.
Mostly, you should only use one view controller per screen. Essentially the rootViewController of the current UIWindow should be the only UIViewController with a visible view.
Each different screen should have a different view controller i.e. one controller should not control more than one screen.
You should NOT nest custom UIViewControllers within a view hierarchy.
If more than one UIViewController hangs off the application’s UIWindow, only one of these will get the messages for changes in orientation. The other(s) will NOT get these messages.
Nested UIViewControllers are not guaranteed, or likely, to receive messages for changes in orientation or lifecycle messages such as viewDidAppear:, viewWillAppear:, viewDidDisappear: and viewWillDisappear: even though they inherit from UIViewController. Only the topmost UIViewController is certain to get these messages.
Please clear point number 2 and 3
because when we use UINavigationController or UITabBarController we use multiple subclasses of UIViewController. And ios device has only one screen.....
This article Abusing UIViewController highlight apple suggestion
Note: If you want to divide a view hierarchy into multiple subareas
and manage each one separately, use generic controller objects (custom
objects descending from NSObject) instead of view controller objects
to manage each subarea. Then use a single view controller object to
manage the generic controller objects.
and in apple docs under heading of Coordinating Efforts Between View Controllers apple saying
Few iOS apps show only a single screenful of content. Instead, they
show some content when first launched and then show and hide other
content in response to user actions. These transitions provide a
single unified user interface that display a lot of content, just not
all at once.....
My requirement is NOT to use any container or modal or popover, I want to do manual management, I have two view controllers VC1 & VC2. VC1 is the root view controller now I want to switch/transit/move to VC2 what should I do?
VC1 should be the only subclass of UIViewController and VC2 should be the subclass of NSObject to manage a particular view in VC1 hierarchy?(the show hide thing by apple doc).
VC2 can also be the subclass of UIViewController, I just remove VC1 from root view and add VC2 as root view?
or what is the correct way?
Container view controllers (like UINavigationController) allow working around the one-VC-per-screen rule. Since iOS 5, developers have been able and allowed to write our own container controllers (which aren't actually much different from normal VCs). Generally this means that writing non-VC controller objects is less necessary than it used to be.
In your situation, where you want to replace the root view controller, your option 2 makes more sense. Use VCs where you can, and non-VC controller objects only when you can't. Since you're replacing the whole screen's content, just switching the UIWindow rootViewController makes the most sense (edit: alternately, many devs would just use a navigation controller to present the second view, because it's simple and convenient).

Resources