I’ve borrowed the Whereami code found in The Big Nerd Ranch iOS book and used it in the app I’m writing. My app determines the user's location and displays it in a map in the app delegate, just like Whereami app in the book does. The UIWindow is made visible and displays the map correctly. From this point on, the code is my own.
My app allocates a UINavigationController, sets the root view controller, and proceeds to allow the user to view other view controllers and perform other methods after navigating to them.
At some point, a view controller contains a button labeled “MAP” that, when pressed, should display the map showing the user’s current location.
How can I get the app to display the UIWindow that is in the AppDelegate.m? I assume the app delegate is continuing to determine the user’s location, and I want the user to have the ability to display the map at will.
My current code allocates a MapViewController when the “MAP” button is pressed, but I can’t figure out how to get the UIWindow which is in the AppDelegate.m to display.
I’m thinking I should be able to do it by having a pointer to the UIWindow in the MapViewController. Is this the right approach? Do I need anything else? I'm using Xcode 4.0.2, Snow Leopard, and testing on an iOS 4 device. I'm new at this, and I don't want to get confused by upgrading to Lion, a higher Xcode, or iOS 5 yet.
Consider using presentModalViewController:animated: (it's a method on all instances of UIViewController and its subclasses). There are a variety of transition styles you can use, like a flip or a fade.
On iOS you very rarely work with UIWindow objects. You pretty much set one up when your app launches and you leave it alone. Everything is done with UIView instances or the UIViewController instances that manage them.
Related
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.
I have a very very old iPhone/iPad app, actually it was my very first Objective-C app, I started learning iOS programming on it. Now I want to update it a bit but have following problem:
The app has never had any viewController. When I started writing it, I wasn't familiar with MCV and Interface Builder. First version was just for iPhone and it made the UI manually by just positioning UILabels and UIButtons in UIApplicationDelegate's didFinishLaunchingWithOptions via addSubview directly into self.window (there is MainWindow.xib but it's empty). A couple of months later I created iPad version. It has all the UI created in Interface Builder in a single MainWindow_iPad.xib. There are no other xibs, just UILables and UIButtons placed directly in MainWindow_iPad.xib and no view controller was used again.
Now, a couple of years later, I want to update this veteran app a bit. I want to add a root view controller so I set window.rootViewController in UIApplicationDelegate's didFinishLaunchingWithOptions. I have no problem with the iPhone version, it works a treat. But I have troubles with the iPad one. After setting window.rootViewController, the app doesn't interact to any touch at all. It loads, the UI is created but it's just frozen.
Any idea what could be wrong? Thanks a lot!
Don't tell me I should throw it away and write it again from scratch in a normal "experienced way", I know this would be the best way but I don't need to update it that much to waste so much time.
I am a newbie in all this as will be apparent really soon.
I am using the iOS: Application: Tabbed application template. I have placed a UIImageView in the first view and two standard rounded buttons. One button is attached to an action in the FirstView Controller which places a picture into the UIImageView. The second button is attached to an action in the AppDelegate which calls a method in the FirstViewController which in turn places a second picture into the UIImageView.
The AppDelegate method does not replace the picture. It doesn't crash… it just does not seem to do anything.
How can I manipulate the view in the First and Second View Controller from the AppDelegate?
#dasdom
Well that's one issue explained. I've been reading the theory of MVC and trying to put it into practice now. Short version is I am trying to write a Battleship app for practice. Was planning on using the first screen to setup the game pieces, prefs, etc.. and use the second screen for actual game play.
I've created another class to use as my "brain center" but I ran into the same issue of not being able to manipulate anything on the screen for the first or second views. (That's why I tried the appDelegate).
That's my life story right now… can you throw some pointers my way on how to proceed and how to solve my one of many problems?
First you shouldn't do that. The AppDelegate should only be responsible for bringing the first view onto the screen.
Second you should have a look into the Model-View-Controller design pattern. Search for it in your preferred search machine.
But I you really still want to do that you should have a look into delegation and/or notifications. For example you could send the First View Controller a notification from the AppDelegate to change the image.
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.
Is it more appropriate to have one shared instance of and iAd for my app or can I create a new instance on each page of a navigation app? It seems Apple's sample code has only one ad that is used one each page. From my perspective more ads means more money. Is there an issue doing it in this manner or am I looking at this incorrectly?
Creating a new instance for every page would be standard. It is non-standard and to try to use the same instance across different pages. (To do that you'd need to remove the ADBannerView from its superview and then add it as a subview of the next view.)
My guess is that the amount of money you'd receive would be approximately the same either way. If you could get more money one way or the other it would be a bug that Apple would fix.
I think honestly you can do it either way. I have an app that is a paged scroll view that has an ADBannerView just off screen (below). When an add gets loaded the scroll view shortens by the height of the ADBannerView and the AdBannerView gets moved up. Its the same object for each page of the UIScrollView.
Some might argue though that my app is really only 1 view, since each 'page' is part of the same ScrollView.
According to the Apple sample code, you should use one instance. If you download the iAdSuite samples, you'll see this in the ReadMe.txt file:
Note: If your application has multiple tabs or views displaying an iAd
banner, be sure to share a single instance of ADBannerView across each
view. Then, before your users navigate to a new view, set the shared
instance's delegate property to nil, remove it from the old view
hierarchy, then add the same instance to the opening view and set its
delegate to the appropriate view controller.
Apple encourages you to use one instance of iAd Banner per app as a best practice. You can read the following technical note for how and why:
http://developer.apple.com/library/ios/#technotes/tn2286/_index.html