What's the MainWindow.xib nib file for? - objective-c

I am new to iOS developement, and i am trying to understand the whole cycle of iOS application developement, and i feel there's a missing part i just don't get it..
if the MainWindow.xib that is generated automatically by Xcode has a view that loads another xib/nib view inside it, then why we use it ?

Your application needs a window so the system can display it to you on the device screen. In the window are various views which represent different areas of your application that users can interact with. Views can either be entire user interfaces, or individual UI controls.
The main window interacts with your application delegate to handle events that your application receives through the views.

Related

Difference between NSWindowController Vs NSViewController

I am coming from iOS background and starting to learn Cocoa. On iOS unless we have multiple targets for iPad and iPhone we usually have one Window and manage the screen using UIViewControllers. Where every new screen will most of the time will map to a UIViewController.
However on cocoa this seems to be the otherway around where a new screen/window is manage by NSWindow and it's subcomponents are managed by NSViewController. So if I have multiple window app I should have separate NSWindowController for each window.
Is this approach correct or am I having a misunderstanding ?
With iPhone SDK and Leopard SDK, they introduced view controllers, or NSViewController and UIViewController. As their names suggest what they do is to manage views
The view controllers are for managing views. Current trend in UI design is Single Window, Multiple View. What it means is that there is one Window and inside of it, different group of views designed for different purpose can be swapped in and out. So, the View Controllers handles these for programmers for well-established pattern.
Currently view controllers are very important for iPhone and iPod touch programming, because the platform is based on Single-Window and Multiple View model. However, it doesn’t seem to me that using view controller is very popular for Mac.
how about the window controller like NSWindowController? Its counterpart, UIWindowController doesn’t exist for the iPhone and iPod touch environment, because there is only one window for those environment.
Unlike view controllers, the NSWindowController is for document based programs. Well, document based program can use multiple window. So, it is reasonable to think that NSWindowController is for document based programs as Apple’s document says.
I also come from iOS and started coding Mac apps a while ago, learning mostly from Apple's documentation.
My impression is that on the desktop, you almost never need NSViewControllers (one big exception would be a window with tabs and multiple views, like the GarageBand welcome screen).
Most of the time you have one NSWindowController per window. Learn first the relation between NSWindow and NSWindowController (and NSDocument, if you are making a document-based app).
Once you got that right, start experimenting with NSViewController.
UPDATE: It seems that since the introduction of storyboards for mac apps too, Apple expects that most of the view presentation logic should be migrated from the older NSWindowController to the newer NSViewController, more in line with how an iOS app is structured. I am not very knowledgeable on exactly where to draw the line, or what kind of code should remain in the window controller (or whether it still needs to be subclassed at all).
A Window Controller creates a traditional window and has all the traditional APIs.
A View Controller can also be shown outside of another view. It then gets a window frame but does not support the full traditional Window Controller API.
In addition to custom, modal, and show, a View Controller can also be presented in the modes sheet and popover.
So, View Controller has more presentation options and a more streamlined API but probably a few limitations in cases that are covered by the traditional Window Controller.

XCode/Cocoa Mac Changing Views

I'm having trouble figuring out how to change between different custom views in my XCode project.
I have my Main nib file, consisting of 1 main window, and 5 custom views. The main window consists of 5 buttons, all which need to connect to the different views. So for example I click on button 1 and it closes the current menu and loads custom view 1.
I'm having trouble figuring out how this would be done.
I guess I would create IBOutlets for the 5 different buttons and the 5 custom views, and connect them to different methods such as openView1, openView2, where each method would close the current menu and load the custom view?
Could anyone help me code-wise how I would achieve this?
Any help greatly appreciated.
Thanks
So essentially you want a tab view?
You can make an NSTabView in Interface Builder. Set the number of tabs to 5. Then lay out the contents of the views you want inside that.
If you are happy using the standard system provided visual look for your tabs, then you're done. If however you want to have custom buttons that switch tabs, read on.
With your tab view selected, set its style to Tabless:
This makes the tab buttons disappear. That means that switching between views needs to be done through code. First you'll need an IBOutlet that represents your tab view itself: connect that up. Then write an IBAction method for openView1:, that might look something like this:
- (IBAction)openView1:(id)sender
{
[tabView selectTabViewItemAtIndex:0];
}
Make yourself a button (that sits in your window somewhere outside the tab view, otherwise you'd only be able to access it from one tab!) and connect it to this action.
This is probably the easiest way to get going with an interface like this. There's a whole bunch of ways to improve on it depending on how you want to structure your code. For instance, it sounds like you're coming from iOS development, where you'd make a UIViewController for each tab. Well, on the Mac there exists NSViewController, so you can use a similar pattern: but if you do you'll need to write some code that handles getting your view controllers' views into your tab view. It doesn't happen automatically through Interface Builder like it does on iOS. This tutorial should get you started if you choose to go that route.

Programming a Universal App in iOS

When I am programming a universal app, lets say I have an IBAction like so:
(IBAction)magicCode:(id)sender {
textField1.text = "TEST";
}
Do I need to create a new IBAction for each view (iPad and iPhone). I can't have textField1 twice in header file, so I am just wondering how everyone else does this. Do I need to put a textfield in the iPhone app with a different name than the one in the iPad app? Or is there some other way everyone else is doing this?
Do I need to create a new IBAction for each view (iPad and iPhone).
First, actions are typically included in view controllers, not views. I think that's probably what you meant, but I point out the difference because I've seen a lot of people get confused on this point.
When you're creating a universal app, i.e. a single app that adapts its UI to the device (iPad or iPhone/iPod Touch) on which it's running, a common strategy is to provide different view layouts that make the best use of the available screen size, but to use the same view controllers. So, for example, say you have an app with a master/detail interface. On small devices, you'd present the master part of the interface first, and when the user chooses something you'd display the detail part of the interface. On an iPad, with it's larger screen, you'd display both master and detail interfaces simultaneously in a split view. Comparing the two, the views are likely to be different, and the way the view controllers are presented is different, but the view controllers themselves should stay the same. This is a good thing, since much of the work of creating an app goes into creating the view controllers.
If your app is similar to what I've described (or if you can make it similar), then no, you don't need separate actions for iPad and iPhone because you'll be using the same view controllers in both cases. There may be times, though, when the behavior of the app on the two different devices is different enough that it makes sense to have iPad-specific and iPhone-specific view controllers. You might still be able to use the same actions by deriving each of those from a common parent class that contains the actions. If not, you'll need to have each class implement its own actions.
No, you can have the same IBAction and IBOutlet in a UIViewController dealing with textfields in two different Nibs (one for iPhone and one for iPad). That's the whole point of separation between View Controller and Views in MVC architecture.
Just use the same UIViewController as File's Owner in both the Nibs and make all the appropriate IBOutlet and IBAction connections and everything will work.

One xib file or multiple xib files

I made a tab bar application that has only one xib file. If you have have made tab bar applications before then you probably know what I did so I don't really have to explain it. I deleted the two xib files and used MainWindow.xib. I just added views to each tab bar button and assigned view controllers to each of them.
So now I have a tab bar application with multiple views and buttons and only one xib file. Would it be better to have a separate xib file for each view in order to conserve memory? Does it make any difference?
Also, why is the tab bar template so weird? Is it somehow better for resource management? In every tutorial I've seen about making tab bar apps people deviate from the template.
Yes it is better for resource management to have multiple xibs. When a xib gets loaded it loads all of its content at once. If you have a tab bar application for instance, each of the views associated with a tab will be in memory at the same time, which is inefficient.
However, if your application is simple enough it doesn't really matter, so do whatever is easiest in that case.

Where should I put some code for loading application data?

I have a tab-bar and navigation controller application (like Youtube app or Contacts app).
Where is the correct place to have the code for loading some data from the web? These data are necessary for all the tabs of the Tab Controller and the app can't display anything before all data are downloaded and parsed from the app (except a loading indicator view of course).
Up to now I put it in the AppDelegate but it somehow doesn't feel right..
What's the correct way to do it?
Thanks!
For a simple application, doing this in the application delegate is okay. I would probably do it in my main view controller, however. I would also probably put some defaults on those tabs so that the user sees something there, even if there is no internet connection (although this may vary between apps, and may not be appropriate in your case).
The most important thing to remember is that wherever you start loading this data (whether it's in the app delegate or your controller's viewDidLoad method), you should kick-off whatever downloads you need and establish whatever notification system is appropriate and return as quickly as possible. I.e., don't block in either of these delegate methods.
In general, though, since it sounds like this data is related to the display you are creating, it's probably appropriate to contain it's loading inside the view controller itself.