I have been struggling a little with my first real iPhone application and wanted to get some advice on how this should be structured. I am looking for some best practices in terms of creating UI components and linking them together to create the application flow (create views/controllers programmatically vs. with Interface Builder, etc...).
Overview:
I need to show a "Login" view on application start up.
--Show "Signup" view if they click the sign up button.
Once logged in... I have a TabBarController loading 4 views. These 4 views will have to load sub-views (master-detail like).
My question is:
1) What is the best way to piece this navigation structure together? Create each view as a .xib with a corresponding ViewController? How are these glued together?
2) How should I handle the Login/Sign up navigation, no TabBar should be shown on start, but will need it after authenticating the user.
Bonus Point) Are there documented best practices for this kind of stuff? I have been hacking together some workable code, but I got very lost and want to start over doing it the correct way.
I know this may be a little confusing, all and any help is much appreciated.
EDIT: For the Login view on top of the tab bar I used this, pretty simple.
LoginViewController *loginViewController = [[LoginViewController alloc] init];
[loginViewController initWithNibName:#"Login" bundle:nil];
[self.tabBarController presentModalViewController:loginViewController animated:YES];
When you create a new tab bar based application in XCode, you are pretty much already set up the way you would like - there's a main XIB that loads views for each tab from separate XIB files. You have one XIB per tab. Note that as you change types or add tabs you need to specify the proper view controller type in both the XIB with the tab bar, and in the XIB that you use to create your view!
As for the login view, a common approach is to use the tab bar as above, but in the app delegate applicationDidFinishLaunching method present a modal view controller that shows the login screen. The modal controller hides the tab bar and everything else until they are done, then it can be dismissed.
1) What is the best way to piece this navigation structure together? Create each view as a .xib with a corresponding ViewController? How are these glued together?
Use UINavigationController and push your custom views onto the navigation stack as needed. Check out the example Navigation Controller application via Xcode's New Project option to get a feel for how this works.
2) How should I handle the Login/Sign up navigation, no TabBar should be shown on start, but will need it after authenticating the user.
Set up a view for login (I would use a UITableView with one section containing two rows for username and password, but that's my own preference). Set up a second, separate view for sign-up fields (again, I would use a UITableView for this, to keep the layout clean and consistent).
Perhaps use a view animation to pop up the tab bar after successful authentication.
Bonus Point) Are there documented best practices for this kind of stuff? I have been hacking together some workable code, but I got very lost and want to start over doing it the correct way.
You'll end up rewriting your project several times — which is a good thing. Do check out Apple's sample applications (available from the iPhone ADC site) as these contain several "best practice" ways of using several of the UIKit components. As to putting together a larger application, keep your design as simple as possible and reuse as much of Apple's UI components as possible. You can always customize later.
In my opinion, only Cocoa programming examples and very simple applications are suitable for a single nib file. Otherwise you should spread your interface components across multiple nibs. This means each nib is smaller and when loaded into memory will only load those components as necessary. This will improve performance in your application and can help logically organize your program and make it easier to debug when issues arise.
In my tabbar apps I use MainWindow.xib to contain the main window and tabbar but I break up each tab into a seperate nib for the reasons above.
Apple offers the following guidelines:
When creating your nib files, try to keep the following guidelines in mind:
Design your nib files with lazy loading in mind. Plan on loading nib files that contain only those objects you need right away.
In the main nib file for a Mac OS X application, consider storing only the application menu bar and an optional application delegate object in the nib file. Avoid including any windows or user-interface elements that will not be used until after the application has launched. Instead, place those resources in separate nib files and load them as needed after launch.
Store repeated user-interface components (such as document windows) in separate nib files.
For a window or menu that is used only occasionally, store it in a separate nib file. By storing it in a separate nib file, you load the resource into memory only if it is actually used.
For more information you can visit:
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/LoadingResources/CocoaNibs/CocoaNibs.html#//apple_ref/doc/uid/10000051i-CH4
Related
I've been tasked with creating an app, but I have zero experience with iOS development. I have general programming knowledge, particularly with Java, JavaScript and PHP (I'm more a web developer than a programmer). I have dabbled with C, Xcode and various other languages and IDEs in the past, but I remember very little.
I've been following Apple's Developer Library tutorials, and I'm at around the Language stage, where I'm come to a grinding halt. While I slowly progress through learning the basics of Objective-C, there are a few things I'm very confused about regarding development in Xcode that various tutorials seem to completely skip over or just imply that you know what to do, or some just stop right before the part I'm having trouble with.
1) Storyboard - yes or no?
Is it better to start with an empty application and work with the
files or create a template (in my case a tabbed application) and work
with the storyboard?
2) If using a storyboard, do I still need to have a .xib?
Are the User Interfaces more like global templates that the view controllers implement?
If I wanted a different layout for each tab of my app, would I create a .xib for each tab, or just edit the controllers in the storyboard? Am I correct in understanding that the storyboard can have multiple instances/relationships of the same controller, in which case having .xib's would make more sense?
3) If using storyboard, where do the implementation and source files come from?
This is probably a stupid question. I know you can just add them via File -> New, but I don't know how to associate those files with a view controller. Is there a way to have the files created automatically when adding a controller into the storyboard?
Since you're just starting, you should use Storyboards because it lets you link different view controllers(pages on your app, essentially) visually and outside of code. For example, you can link your UITabbedViewController (the part that manages the content of the other tabs) to the pages that represent the content of the different tabs. Basically, your storyboard would have the tabbed view controller in a parent-child relationship with the sub-controllers. You would have one instance of each -- the tabbed view controller, managing an instance of each of the tabs' content and controller. This is the same regardless of Storyboard or xib, but you can connect this more easily in the storyboard.
You can still use a .xib(nib) file for stuff like Custom Table cells or in cases where you want to separate a view element or controller from a storyboard where there are other constraints.
In the storyboard, you subclass the controller class on the sidebar in the visual editor by entering your subclass of say UITabbedViewController in 'Custom Class'. In your file associated with 'MyTabbedController', you implement your stuff.
Great book:
http://www.barnesandnoble.com/w/beginning-ios-6-development-david-mark/1113216077?ean=9781430245124
Good luck!
Storyboards can be appropriate for small applications, where you have ten or twenty screens. When your app contains more than that, you will just get lost in storyboard schema, where all your view controllers will visually look the same.
I prefer not to use storyboard, just separate xib files for each controller.
If you use storyboard, you can create xib files for other parts of application that is not related to SB, and view controllers that is involved in SB has their interface stored in SB, meaning you will have to design them in there, in this one huge storyboard file. I find this very uncomfortable.
As you are new to IB, I would like recommend you to take a look at Auto layout. There is no magic anymore :)
To answer on a point-by-point basis:
I typically use the "Single View" template. It provides everything you need for your first view and can take it from there. It's a clean slate but it already has that first view which will be exactly the same code in 99% of the applications you make.
No, the storyboard file is your xib. You used to have to make a new xib for each new layout, but then Apple introduced storyboards. A storyboard is basically all of your xib's in one file. Rather than make a new xib, drag a new ViewController object onto the document. You typically only have 1 storyboard file or 2 if you want to support both iPhone and iPad layouts.
I don't think you can have it create your source files automatically, but its fairly easy to connect them manually.
Select the ViewController that you want to connect to your source files by clicking on that black bar beneath it. Then go to the bar on the side and go to this panel:
There you enter the name of your custom ViewController subclass where I have put "MyViewController". Hope that helps!
i'm currently developing an app for both Android and iOS, thing is... I started with Android and my app has several Activities with different layouts (Screens with different GUI's, if you are not familiar with android), most of them display very different contents; maps, lists with data from databases, images, text fields with buttons and so on (And most of the time the orientation of the screen changes).
The problem comes with iOS:
How do I create more windows from IBActions? (Is this a correct approach?).
Once I create a Window, how do I create a new Interface? (Do I need another .xib file?)
If once the user finishes with one Windows, does the previous window remains in memory and can be re-opened? (Can I use a navigation tab, even though the first windows was not a using it?) This is a major problem since iPhones do not have a back button and Android relies a lot on those...
Also, if I can't split my program in several windows, wouldn't my app use a lot of memory from destroying and building views?
I'm new to Cocoa development and I have already read a book about Objective C programming (which only teaches syntax and so on), another one about simple iPhone apps (all of them were done in one window, changing the views programmatically) and I'm currently reading another one, but i'm unable to find a simple answer to my problem...
I mean I get Obj-C and how to build iPhone apps (well kind-of) but maybe the problem is that I come from a more straight forward development in Android. Each time I see an iOS project, I see it like a total mess, and the documentation in developer.apple.com doesn't help much either, I'm unable to find what I want.
Hope someone has gone through this already and is willing to point me in the right direction, thank you!
I recommend that you start with the View Controller Programming Guide at the apple developer web site. I think you will find it very helpful.
To answer your questions, you can develop each of your views independently. You depending on your purposes, developing each from a nib file could work. In the app I'm working on now, I have some that I develop programmatically and some that I bring in from NIB files. It's all up to you. The guide I mention above discusses both approaches.
Regarding loading views from button presses, you can do that. Depending on the view controller you use, it can be very easily accomplished. WIth the navigation controller, for example, you just create an instance of the view and push it onto the stack. When you're done with the view, you pop it off and your back to your previous view.
With regards to memory, that is always a concern. You might want to take a look at The Memory Management Programming Guide.
Good luck. I'm just starting out with Android development myself.
Chris already provided a great answer but there are a couple of points I want to add to adress specific questions.
iOS apps normally only have a single UIWindow. Within that window you may present multiple views.
Apps are normally organized into several logical screens worth of content, each managed by some UIViewController subclass.
Each UIViewController instance has a root view which may contain many subviews. A UIViewController's view is expected to fill its window or some frame provided by one of Apple's container view controller classes (UINavigationController, UITabBarController, UISplitViewController, and so on). You should not add one UIViewController's view as a subview of another UIViewController's view.
UIViewControllers will attempt to unload their views when the application receives a memory warning if the view is not visible. See the class' life cycle methods like -viewDidUnload. You should support and take advantage of this behavior to reduce your memory footprint. Keeping UIViewControllers in memory without their views loaded should have a minimal overhead, allows you to keep some persistent state, and each controller's view can be reloaded when needed.
Normally to transition between views a control will send a message to the current view controller (often via an IBAction binding). The current controller will then trigger a transition to another view controller. It might do so by creating a new view controller and pushing it onto the current navigation controller or presenting the new controller as a modal. It might have a reference to some existing controller and present that. It might dismiss itself from a navigation stack to reveal the previous controller. It might even pass the message up the controller's hierarchy until some parent switches the visible tab, dismisses or presents a modal, and so on.
You might also trigger smaller transitions by responding to an IBAction by adding, removing, hiding, or moving subviews of a UIViewController's root view.
Flash Builder 4.5.1 Now enables you to build one application and Compile to multiple Devices
UPDATE: Try XAMARIN, it's part of Visual Studio:
https://www.xamarin.com/
In my iphone, in the section where I can make a call, I can view recent calls and I can also view my contacts.
I am referring to the contacts application.
I'm watching the stanford iphone vidoes, and they recommend creating a seperate NIB file for each view.
From what I understand, each nib/view will be managed by its own subclass of UIViewController.
Can someone, at a high level, describe what the contacts application might be comprised of in terms of nib's, controllers and views and how they would work together?
The contacts app is, unfortunately, a bad example. It's functionality is implemented at a lower level in the OS, as it is shared between the address book app, the phone app, and it can be implemented in your own app if you wish. Thus, the app is really just another front end for the feature.
Basically, the app is a UITableView with search that sends you to a UIView containing a UITableView and some text / image fields. Of course, there are editing and creation buttons to handle CRUD, but basically that's it. Each page would have it's own UIViewController and NIB file (assuming Apple follows their own directions, which they may not) ;)
Underneath, you have a core data store, but there's no much complexity in the data structure there, either. If you really want to analyze the database file, that's possible as well.
Hope that helps
At a high level, you have a UITabBarController that handles the tabs along the bottom and the switching of the five view controllers. Each of the view controllers, with the exception of the "Keypad" tab, uses a UITableViewController as the root controller of a UINavigationController. And it looks like, for the most part, where you are in the UINavigationController "stack" is remembered for each tab.
Each of the UITableViewControllers have a fairly simple implementation of the standard UITableViews. The implementations of UITableView are probably canonical examples of how to use UITableViews -- namely, what action to trigger depending on whether there's a disclosure button and what gets clicked.
Hope this helps!
I have a User Filter section of my iPad app. There is a segmented bar with 5 buttons for 5 types of filters.
Clicking each of the buttons will load up the respective view..
My question is.. would the best way to handle the UI of each filter to have several views in this nib and load/unload accordingly.. or would best practice be to create the information in a scrollable view?
below is the setup..
http://imgur.com/iuufU.png
Thanks in advance...
Generally, go with separate views. The Scrollable view is an approximation of what you're trying to achieve (by the looks of things), whereas the separate-views more closely reflect your aims.
Some typical dvantages:
if you change your UI design, e.g. if one of those filters has to go in a different page, but 4 stay here ... then it's easy to move the whole View without changing the eixsting ones.
you can put each view in a separate NIB file (if they're different), or loaded from a separate ViewController instance (if they're the same), and you get some of the advantages of Apple's automatica memory management of VC's / NIBs.
Usually, people start with the same view for each filter, using a single VC class (instantiated multiple times, once per tab).
Then, as the app evolves, they find that one tab needs a different layout, so they add another VC class, and only need to update the alloc/init line for that one tab.
Here's another very basic question. Is there an easy way to rename the rootviewcontroler? Say I decided that I needed to add a page before the current rootview (splash page, mini data snippets from the main app, etc.) How hard would it be to create another rootviewcontroller? I guess you would just take the current one and edit out lots of stuff.
Thanks.
Make a new viewcontroller for any view or set of views that manage different user experiences or tasks. I have a root viewcontroller in most of my apps to handle transitions and provide a few global methods, and then a viewcontroller (VC) for my settings UI, another for my game, another for my high scores list, etc.
Adding new VCs are as simple as the first one you added. If you are a bit timid about VCs, there are other classes that can keep some of the VC handling hidden in their code, like the Navigation Controller.
Please read up on VCs to see how they are intended to be used. Here is one.