I would like to develop an application for iPad, using a layout like that shown in this link:
https://skitch.com/sparkoletto/g13ck/ipad-views-layout
As you can see in the image on one page I would like to insert a UITableView (B), two UIScrollView (one vertical (D) and one horizontal (A)) and a simple UIView (C).
What is the best way to develop such interfaces?
It 'best to use a single ViewController that manages all the views that I need, or create a ViewController for each view, and then combine them all together in another UIViewController?
Thanks
I disagree with #TomSwift. When these things get complicated, it's very helpful to break them out into their own view controllers. You'll create a view controller of the correct type and then [self.view addSubview:vc.view] at some point.
The problem with making one complicated view controller is that it becomes delegate and datasource for too many things that are internal details of individual subviews. Your delegate methods now need to check which tableview is talking to them, for instance.
Splitting them up also makes it much easier to manage rotation, particularly if you want a different set of views displayed in each orientation. This is good for memory management as well, since the VCs can automatically unload the views you aren't using anymore.
Breaking things up too small is of course also a problem. There is a cost to having separate view controllers, especially if they interact with each other. Having a good feel for when is the right time is the mark of an experienced developer. But for the view you showed, I would almost certainly break it up. Your situation looks very much like UISplitViewController.
Likely a single view controller, IMO, unless you plan to reuse some of these panes in other places. In which case you could implement a "container view controller" with a single view to handle the layout of the child view controllers.
Typically view controllers manage "full screen" (or nearly full screen) views. The exceptions are fairly rare - UISplitViewController is one.
Related
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.
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
Is it a good practise to creates views in xcode and hide them and when required show them?
I am asking that because I prefer to create views visually and not in code.
If the view is to complex(a lot of subviews) should I create a new view controller to it?
I know there isn't a specify question here but I really need a clarification on this matter.
Regards
One of my first iOS applications had a tab bar and views that the user could switch between. Originally it was done by hiding and showing the right views depending on what the user pressed on the tab bar. This ended up being a complex disaster.
I then rewrote the app so that each tab bar view had its own UIViewController with its own set of views. That turned out to be so much easier to manage. (I also changed from using Interface Builder to straight code for creating the views, but that's beside the point and you can continue to use IB if you want.)
As for me, I prefer folowing practice:
Usually, a use storyboards,where views are placed, but if a view is complex, I create a separate XIB file, arrange all subviews there, and then in storyboard drag an UIView subclass and connect my XIB view with it.It helps to avoid mess in storyboard.
As for hiding views, I also don't recommend such practice as it can become very complex to understand your code and all those views are allocated when XIB is loaded, so the mobile developing rule "do as lazy as u can" is not met. We should try to spend as less memory as it's possible.
UIView is the best way to create iOS app, esp. if you want to reuse the code.
For example if you have same view to present in iPad n iPhone then using UIView can result in lots of similar code in View-controller
In another case if your view might need to have multiple table view it can be quite complex to handle each with delegates in ViewController. But separate view will solve this problem.
I have made my 1st open source code after learning how to use View
https://github.com/bishalg/BGRadioList
which I had learned from
http://www.raywenderlich.com/1768/uiview-tutorial-for-ios-how-to-make-a-custom-uiview-in-ios-5-a-5-star-rating-view
About the hiding view - I have used lots of hide and show view codes in my apps but believe me at one point it will become complex and unmanageable if you have lots of views.
Here is a screenshot of a view that I have right on my device.
The design issue that I am having here is that the top part of the screen is always going to be static - as far as its placement. The rest of the screen are a row of buttons added to this view programmatically. The arrows represent the idea that you could swipe in 4 directions(from top, from bottom, from left and from right) which would animate a new view onto the screen. This view is the same instance as the view before it. In fact all these views are the same instance but the buttons will be different.( i dont want to get too specific here.)
My design right now calls for pre-loading the views ahead of time. The data for each button for each view will be in core data. I will not know ahead of time how many views there are. One view might just have a view to the right that you can swipe in from the right and that view might have a top and bottom arrow - that would allow you to swipe from bottom or top that would be another view(same UIView subclass). So basically a tree of views.
I guess I am trying to figure out my options. A NavigationController is not really what i want because i have no need for a navigation bar, although in my mind it makes sense that i would have an array of view controllers here each with its view property pointing to each view that is allocated and then as i swipe i would bring in the appropriate view by using the view controller index.(through some animation code)
Another possible option would be UIScrollView but that seems cumbersome and may not be what i would really want.
One of the easiest setups would be to create a XIB file that would consist the top part of the screen and on the bottom an empty UIView that i would programmatically populate with the buttons(and their unique data). The problem that I am havign with this is, is how would i swap the views this way. I guess i could make the rootViewcontroller the first viewcontroller instance with the first view and then swap them.
I guess I am wanting to see if anyone had any questions or suggestions to come up with the easiest(most modular) approach to swiping in different views. Is using an array of view controllers the way to go?
A couple of thoughts:
This screams custom container view controller to me (if iOS 5 and above). See Creating Custom Container View Controllers in the View Controller Programming Guide for iOS.
You talked about using UISwipeGestureRecognizer. You could always contemplate UIPanGestureRecognizer, too. It's nice to have continuous gestures. Think about reading a book where the page swipe tracks your finger, but you can stop and go back, mid gesture. Sure, start with swipe gestures for now, but if your UX lends itself to it, you can always contemplate continuous gestures in the future.
You said that you're planning on "pre-loading the views ahead of time". Generally, given the limited memory capacity of mobile devices, you'd want to be more conservative than that. Maybe load the current view, and the four ones that you're likely to go to in each of the four directions (so that you can present them instantaneously), but leave it at that. Once you go to one of the four possible destinations, then go ahead and release the ones that are not reachable from the current one and tee up the ones that are.
One Xib is enough for you (for this part of your app anyway).
Don't use a UINavigation Controller. The NavController metaphor is one of a stack of cards. You don't have that data structure.
The general idea is one ViewController for one screenful of stuff. If you feel the need for two viewControllers (one for the top part, one for the bottom part) then you are going to have to look at custom container controllers, to ensure that the contained controllers receive their instance methods correctly (viewDidLoad, viewWillAppear, etc). An example container controller managing a pair of viewControllers is the iPad splitViewController. But I don't think you need to do this.
I suggest placing a scrollView on the lower half of the screen and using that to manage your data views. If the upper part of the screen also needs to change (under other conditions) you could even have two scrollViews, one up top, the other below. They can be paged, and contain views that are the exact size of the respective screen portion. They can share their single containing viewController as a common location for their delegate methods.
I can't really help you with more detail, as I don't have a precise enough idea what you want to achieve. Perhaps you should try and implement it one of these ways and come back here with more questions as your ideas become concrete. Start out with the simplest idea (eg scrollView inside a single viewController), only chuck it out when you find you have to break it!
update
following your comments, I do think a scrollView might work for you. I think that managing a stack of view controllers with a custom container controller (as Rob suggests) could get overcomplicated. You will have to create your own custom container controller, the pre-existing ones such as UINavigationController are not appropriate for your data strucure (from what I can gather anyway).
You won't need to manage tons of UIViews, in fact you only need 5 - one for the onscreen portion of the scrollView, one for the screen immediately left and right, and similarly for the immediate one above and below. You can reuse these views as you swipe, much the way that tableViews reuse their cells. The rest of it will be about manipulating your data so the right content is arranged in the views as they come onscreen.
See my answer to this question for some more ideas on this: UICollectionView horizontal continuous loop
I have a ViewController (with navigation) that needs to show 7 different content layouts. I want to keep the same background and nav, the only thing that needs to change is the central UIView.
If I have 7 different UIViews on the same xib/storyboard, can I hide the ones I'm not using or will that ding performance?
Using segues won't work either because they make a mess out of my custom navigation and animations.
Is there a better way to accomplish what I am trying to do? Thanks for suggestions
solution
My design is too custom for using view controller containment so I decided to mimic the idea with a custom UIViewController and two UIViews. It's not too bad and it works rather quickly.
You should look into using view controller containment, then you can load your views from separate nib files and still provide your custom navigation and animations from your container view controller.
Note: This is only really supported from iOS 5.
Generally, it's a good idea to unload views that aren't visible, however, if your views aren't using too much memory (and/or cpu time) hiding them when they're not in use should work fine.
View controller containment is probably what you should be doing if each view has its own unique functionality (i.e. view 1 is a map, view 2 shows some about text, view 3 is an image gallery). UITabBar might be useful, but it depends on your app.
The performance hit would depend on your views' contents. If you haven't done so already, invest some time into learning how to use Instruments (apple's diagnostic tool). Watching the video titled "Optimizing App Performance with Instruments" in the developer resources would be a good start.
My design is too custom for using view controller containment so I decided to mimic the idea with a custom UIViewController and two UIViews. It's not too bad and it works rather quickly.