How do I make a universal iPhone / iPad application that programmatically uses UISplitViewController and UINavigationController? - iphone

I couldn't find a good answer anywhere to this. I am using a UINavigationController for my iPhone app, with everything is generated programmatically, nothing in Interface Builder. I am trying to port my app to iPad, using a UISplitViewController and my existing UINavigationController, but I am not sure where I should have the logic of my program separating the view controllers for iPhone or iPad.
Do I set up my main file to use a different app delegate or do I use the same app delegate and have the user interface conditionally set up within it?
Besides this, whenever I try to compile my app on the simulator it does not recognize the UISplitViewController or even the condition in which I check if the class exists.
Can please someone put me in the right direction, remembering that I am not using any xibs?

If you want to see an example of a completely programmatic iPhone / iPad interface that uses a split view, you can download the source code of my application Molecules.
Within that application, I use one application delegate, but I set up the interface differently depending on which user interface idiom is present (iPad or iPhone). For the iPhone, I instantiate a root view controller which manages the appropriate interface for that device. For the iPad, I first create a UISplitViewController and attach it to the root window, then create my iPad-specific root view controller and place it as the detail view of the split view controller (with a navigation controller that I use for item selection as the left-hand controller for the split view).
Again, I recommend looking at that application project to see how I set this up programmatically. The code's available under a BSD license, so you can copy and paste this into your own application if you'd like.
As far as the compilation errors you're getting, you will need to migrate your application target to be a universal application using the "Upgrade Current Target for iPad" menu option. Once that has completed, set your build SDK to 3.2. Go to your application's build settings and set its Deployment Target to the earliest OS you want to support with your application (with 3.0 being the farthest back you can go).
Finally, you will need to weak-link UIKit. For how to do that, see my answer here. Weak linking of frameworks is no longer necessary if you are building using the iOS 4.2 or later SDK. Simply check for the presence of the appropriate classes at runtime by seeing if their +class method returns nil.

Related

"viewWillAppear" not call in xcode 4.5 with iPhone 4.3 simulator

"viewWillAppear" not call in xcode 4.5 with iphone 4.3 simulator, but if it runs in iPhone 5.0 or iPhone 6.0 simulator, this method will be called.
why? and what can i do if i want to do something when the view of an controller will appear in ios 4.3?
I think it may be related to the "View Controller Abusing". Check if your container view controller is used correctly. You can refer to this post for detail.
Based on your comments, the problem appears to be the lack of container view controllers in iOS 4. As of 5+ you're explicitly meant to be able to add the view of any controller into the view of any other* and that will generate the appropriate view[Will/Did]Appear, along with all the other newer messages — viewDidLayoutSubviews, etc.
In 4 you weren't explicitly allowed to build container view controllers and there's no deliberate, specific backwards link that connects a view back to its controller.
As a result, when you add the navigation controller to your view it doesn't get viewDidAppear. Because it doesn't know that its view has appeared, it doesn't tell any of the controllers it contains that their views have appeared.
Probably the best you're going to be able to do is to hack around that by (i) checking if you're operating under iOS 4; and (ii) if so, posting artificial viewWillAppear/viewDidAppear/viewWillDisappear/viewDidDisappear to your contained controllers.
Based on personal experience, iOS 4 (at least in 4.3) does actually implement addChildViewController: but not to do what the later, documented version does. So despite it not being an entirely accurate functionality check I tend to use if([self respondsToSelector:#selector(presentingViewController)]) to determine whether I need to propagate these messages manually.
[*] and you should also call addChildViewController: to make sure all messages move correctly in all directions

Return to mainview from webView deployed using storyboard

I created a new project "Single View Application" and designed the mainView with Storyboard. My main view contains a UIButton that opens the camera, the camera scans barcode and automatically goes to a website. Now I created a webView programmatically so that website can open and also created a UIButton inside the webView. Now I want that UIButton to act as home botton and return to mainview. I am unable to do that, please help.
ViewController.m code: http://cl.ly/FKj8
My storyboard looks like:
You really should look into the View Controller Programming Guide -- by switching around the contents of a single view controller, you're making a lot of extra work for yourself with little benefit. By using multiple view controllers when you want to have different "screens" in your app, you can take advantage of storyboarding for easier development, and you automatically get better memory management (read: less potential for crashes), too.
However, to more directly answer your question... if you're putting the WebView into the view hierarchy with [self.view addSubview:webView], you can remove it with [webView removeFromSuperview]. (This means you'll have to keep a reference to the WebView around so you can refer to it when you want to dismiss it.)
I also noticed in the code you posted to cl.ly an unrelated method -deviceModel which uses uname() to get device information. This is a bad idea, for two reasons:
uname() isn't guaranteed to do something useful on an iOS device (even if it currently does). Use the UIDevice class instead if you need this kind of info, or...
Generally, you don't want to test for the device name to enable functionality in your app; instead, you should test for the capabilities you need. (For example, if you look for a device name starting with "iPhone 4" to test for a Retina display, you'll miss the 4th-generation iPod touch, and the iPhone-5-or-whatever-they-call-what's-next. Instead, use the UIScreen class.)

Should I be writing the majority of my code in a controller or the delegate?

I was using Xcode 4.1 and after upgrading to 4.2, things started to become out of date. I am using many examples from different books, such as Big Nerd Ranch Guides, which do not use Storyboards and the Windows-Based Application had been changed to "Empty" Application.
With these new changes, I feel like the books and tutorials I had been using to start have become outdated. In many of these examples, they say to write the methods and variables in the delegate header files for 4.1. With the new 4.2 Xcode, there is an AppDelegate and ViewController. Should I still be writing the methods and class members in the AppDelegate, or should I be now writing them in the Controller file?
I am confused. Does Apple now want us to create our controller and reference it through the delegate?
When your app is run, it creates an instance of UIApplication. You want to know things that only the UIApplication object knows (did we just get switched to the background? did we just open?) so you use the delegate pattern to get it. When you start a new project Apple starts you off with an already-assigned App Delegate. You can open up MainWindow.nib and inspect your App Delegate to see how it is connected to your UIApplication instance (File's Owner, in this case).
In general you only want to put code in there that has to do with the basic functionality of your app. Launch, quit, go to background and come to foreground are when you'll be doing things in the App Delegate.
Most everything else should go in your view controllers or model objects. Since 'delegate' is just a design pattern, your view controllers can be delegates of other objects. For example, if you present a UITableView, you will assign a view controller as it's delegate in order to respond to events such as selection and scrolling. Your app has many delegates, but it only has one App Delegate.
The AppDelegate is really just a "launcher" for your app. Ie: You shouldn't be writing much code in it at all.
If you're concerned with "set up" code, do it in your View Controller, under viewDidLoad.

Converting application to ViewController

What would be the simplest way to convert an existing application with xib files based on UIWindow into a self contained view controller?
Editing post to address comment from OP:
In future apps, you should avoid acting directly upon a UIWindow whenever possible. However, now that you are stuck with an App A that directly acts upon the window, I would suggest that instead of doing a bunch of work to make your app properly use a UIViewController, you can just make App B into an app that uses two windows:
When App B wants to show the content of App A, just instantiate a new UIWindow windowOfAppA, set its rootViewController to the rootViewController of App A, and then call '[windowOfAppA makeKeyAndVisible];'. Once App A is done doing it's work, it can resign key window status by calling '[windowOfAppB makeKeyAndVisible];'.
Again, I emphasize that the technique I am grudgingly describing is terrible style and in the future your apps should only use one window it should only act upon it when absolutely necessary. Whenever possible, do all your work through view controllers.
Previous content of this answer:
What is your ultimate goal? Are you
trying to turn App A into a part of
App B? If so, you don't have to make
any changes to your existing class
hierarchy or nib files. All you have
to do is copy all of the files from
App A to App B and instantiate App A's
root view controller from within App B
(perhaps using
presentModalViewController:animated:)
and everything should work great.

From iPhone OS to cocoa on OSX

I come from an iPhone OS development background. I'm now trying to write apps for OSX, but I don't understand where cocoa on OSX decides where the program gets control.
I can see the main function, but where does program control go from there? Say for example I want to programatically create a window with an NSView in it once the app has finished launching - how would I do that? There is no app delegate created that I can see, in iPhone OS I would wait for the -(void) applicationDidFinishLaunching:(UIApplication *)application
method to be called. I really don't want to use the Interface Builder or NIB files to setup my window/view. How would I go about this?
It's much the same as the iPhone. In your application controller class, override NSApplication's applicationDidFinishLaunching delegate method. If you used the standard Xcode project template your app controller is already instantiated in your Interface Builder MainMenu.xib and set to be the application's delegate; if not you'll need to drag it in there and set up those connections yourself.
Speaking more generally, an OS X app begins its life in the main method, where Cocoa will automatically set up your application's run loop and load the .xib file you specify in Info.plist. This xib is usually where your application controller is instantiated. By overriding one of the methods such as +initialize, -init, -applicationWillFinishLaunching or -applicationDidFinishLaunching (which all have subtly different behaviors) you can load additional controllers and nibs with objects that interact with the run loop at a future date, so you can continue to execute code after your launch method has finished.