iPhone app converted to iPad app shows iPhone xib not iPad xib - ios

I am in the process of converting an iPhone app to a universal app.
I've changed all the xCode settings and added a new MainWindow-iPad.xib
I've hooked all the interface builder references up (e.g. MainWindow-iPad to the appropriate iPad class viewController, window etc)
I've added a new iPad class for the opening view controller and declared it in my AppDelegate.h file, and synthesized them in my AppDelegate.m file:
UIWindow *window;
UIWindow *windowiPad;
AppViewController *viewController;
AppViewControlleriPad *viewControlleriPad;
in the app delegate I check for which device I am running and load the appropriate class:
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
// Override point for customization after application launch.
navController = [[UINavigationController alloc] initWithRootViewController:viewControlleriPad];
// Add the view controller's view to the window and display.
[windowiPad addSubview:navController.view];
[windowiPad makeKeyAndVisible];
[navController setNavigationBarHidden:YES animated:NO];
} else {
//I am an iPhone!
// Override point for customization after application launch.
navController = [[UINavigationController alloc] initWithRootViewController:viewController];
// Add the view controller's view to the window and display.
[window addSubview:navController.view];
[window makeKeyAndVisible];
[navController setNavigationBarHidden:YES animated:NO];
}
And everything seems to work fine - except it still loads the iPhone nib/xib file AppViewController.xib instead of AppViewControlleriPad.xib. You're welcome to ask for more information but I can't figure out how to get it to load the AppViewControlleriPad.xib when running an iPad rather than the iPhone/original xib file.
I thought, perhaps naively, that if the xib file has the same name as the class of the view controller then the ViewController would use that as its xib.
How can I fix it so that the correct xib is loaded for the correct device?

You have a spelling mistake - correct sufix for iPad resources is "~ipad" instead of "-iPad". With "~ipad" your resources will be loaded automatically depending to device.
And you probably don't need another UIWindow for your iPad controllers. You can use the same window at app starting point. Good practice is also to have one view controller (inside you can perform some special things for different devices) and two nibs (one "normal" and the second one with "~ipad" sufix). In rare cases if whole controller behavior is completely different you may want to use two view controllers.

It may be due to the reason that you didn't connect iPad's view controller to files owner in IB.

Related

Storyboard not unloading when switching to another xib

i'm developing an app for the iPhone, and i'm having a bit of trouble with switching views and xibs and storyboards etc. I have gotten everything to work as in switching the views, but when i change to my game view from my main menu, it seems that instead of entirely switching views, it just appends all the objects i added programmatically etc to the same storyboard for some reason, i can see the previous page in the background while the game completely loads and works. The buttons from the previous views also seems to still still work, but are just "ghost buttons" as in i can click them through the new view.
It's almost as if the old view never unloads but just stays there in the background, while the new view gets added on top of the old view. I'm using Xcode Version 5.0.1 (5A2053) and developing for iOS 7. the methods i use for switching views are:
From Storyboard to Xib:
[self presentViewController: [iphoneGame alloc] animated: NO completion:nil];
From Xib to Storyboard:
ViewController *viewController = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"ViewController"];
[viewController setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:viewController animated:NO completion:nil];
Your code to load a VC from an XIB is wrong. You don't create a view controller with alloc/init. You need to use initWithNibName:bundle:. If you pass in nil for both, the system should use the nib name that's the same as the class name.
Why are you trying to mix and match VCs from XIBs and storyboards? That's fairly unusual. Most people either use one or the other, and if you're going to do it, the burden is on you to get everything set up correctly.

Two ViewControllers Orientation

I've come up with a strange scenario, I'm using one NavigationViewController and one ViewController (named- container) in my MainWindow.xib.
NavigationController loads subsequent views, and in parallel, the other ViewController (container) loads some images on top of everything - No matter what view is displayed by the NavigationViewController.
When I rotate the device, the subsequent views of NavigationController rotates as expected but the container and its subsequent views do not rotate.
Here is the screenshot of my MainWindow.xib
and here is the code.
in .h
UINavigationController *navigationController;
IBOutlet UIViewController *container;
in .m (ApplicationDidFinishLaunchingWithOptions)
[window addSubview:navigationController.view];
[window addSubview:container.view];
[window makeKeyAndVisible];
I've also tried creating a separate class and assigned it to the viewController. (Its ViewDidLoad) Method fires but it doesn't come in the (ShouldRotateToInterfaceOrientation)
I read somewhere that IOS doesn't support the orientation for multiple ViewControllers.
I think you should try this because you are trying to use tow views in one navigation.So dont make sub view of window,make subview of main View like:-
[window addSubview:navigationController.view];
[navigationController.view addSubview:container.view];
[window makeKeyAndVisible];
I have't try this code but i am just suggesting idea.
thanks.
There should only be one viewController to a screen, unless you are using container views.
See the Implementing a Container View Controller section of the class reference.
The very short version is that you need to create your own container and then add the two view controllers to it using the methods that they describe:
Here are the essential methods you might need to call:
addChildViewController:
removeFromParentViewController
transitionFromViewController:toViewController:duration:options:animations:completion:
willMoveToParentViewController:
didMoveToParentViewController:

How to show up a Window?

I am learning iPhone development and in my application I have some view but I should use a window, so I want to call a window in an IBaction how can I call a window? I try to use the example with AppDelegate you can see my code :
- (IBAction)start:(id)sender {
self.window = [[[Game1ViewController alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[self.window makeKeyAndVisible];
}
Game1ViewController is type UIWindow.
Best Regards
I believe your app only gets one window. On top of this you place different views. These can be anything that subclasses UIView. These can be controlled by a UIViewController. Usually there is some sort of design style that dictates how the app is structured, between UINavigationController, UITabController, Master/detail.
If you open Xcode and start with one of their templates such as master/detail you can see the transitions between views and how to make one appear/disappear and the interaction between view and view controller .

Issues with running app from MainWindow nib?

I had the entire app (it consists of one view) set up and ran from a View in the ViewController object of the MainWindow nib, INSTEAD of actually having the view ran from the actual ViewController nib.
The app runs flawlessly, however I have two warnings. I learned that these warnings are caused by me running everything from the MainWindow nib rather than a ViewController.
Are there any issues with running an app from the MainWindow rather than an actual ViewController? The app is text based and involves constantly updating UILabels. You can find it here if you'd like to take a look at what I'm talking about.
Right now having it set up this way causes no issues... however I am planning on expanding the app. I tried copy and pasting my Scroll View to the actual view controller nib, but when I did I just had a grey screen. Can I leave the app as it is?
But what is there in your MainWindow.xib file? If you just want to have window object, go to your applicationDidFinishLaunching method and create a window object.
- (void)applicationDidFinishLaunching:(UIApplication *)application{
UIWindow *appWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window = appWindow;
[appWindow release];
}
Or you could have select the option Window-Based application while creating a new project.

how to add an adbannerview to a UISplitviewController

I have made an ipad application using an UISplitViewController, which functions in both orientation. Now I want to add banners to this application. How do I do this? In interface builder I can only add a portait banner to the detailView, which works more or less, but when I turn the iPad and click the banner it opens in portrait mode instead of landscape mode. And the banner can never get the prescribed width for ipad-landscape mode.
Trying to do it programmatically, it tells me that the parent of the adbannerview should be a UIViewController.
This same problem drove me nuts for ages until I found the iAdSuite sample. So, to expand on Erran's answer: Use the iAdSuite sample code from Apple.
Get yourself a working split view app using storyboards.
Include the iAd Framework.
Copy the BannerViewController.h and .m files to your app. Then in AppDelegate.m in "application didFinishLaunching" copy the line from iAdSuite's AppDelegate as per the last line here:
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
splitViewController.delegate = (id)navigationController.topViewController;
UINavigationController *masterNavigationController = splitViewController.viewControllers[0];
_bannerViewController = [[BannerViewController alloc] initWithContentViewController:splitViewController];
In the section for iPhone you need this line:
_bannerViewController = [[BannerViewController alloc] initWithContentViewController:navigationController];
Just before the return statement add this
self.window.rootViewController = _bannerViewController;
Add this at the top of the .m
#implementation AppDelegate{
BannerViewController *_bannerViewController;}
#import "BannerViewController.h"
Or create the bannerViewController property any way you prefer.
Amend the .h as follows:
#import <UIKit/UIKit.h>
#class BannerViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>
That was enough to get it all working. The whole split view app now operates inside the BannerView. That handles all the AdBannerDelegate functions.
Good luck :-)
In the iAdSuite Apple sample code there is a split view controller iAd implementation which you can easily add into your application. :^)
i've taken #ipwnstuff's answer a bit further.
first caveat: iAd only allows you to display in "portrait" or "landscape", and on iPad, this means 768x66 or 1024x66 respectively. this means there's no possibility of confining the ADBannerView to only the UISplitViewController detail view unless you want to roll your own that has a slightly wider view (and thus slightly narrower masterViewController view. i wanted to stick with storyboards, so i didn't want to go this route.
second caveat, the iAdSuite stuff #ipwnstuff pointed to is not immediately storyboard friendly. it creates the UISplitViewController programmatically, and you have to supply the master and detail either via .XIB or programmatically. since i had a working storyboard into which i wanted to integrate iAds, i wanted to extend that. also, the iAdSuite solution does not hide the master view in portrait mode, and i still wanted that.
so … starting an existing iPad.storyboard file, and then integrating with the SplitBanner sample from with iAdSuite as follows:
UISplitViewController *splitViewController = (id)self.window.rootViewController;
splitViewController.delegate = (id)splitViewController.detailUIViewController;
CGRect splitViewFrame = splitViewController.view.frame;
splitViewFrame.origin.y -= application.statusBarFrame.size.height;
splitViewFrame.size.height += application.statusBarFrame.size.height;
splitViewController.view.frame = splitViewFrame;
// initWithContentViewController: the thing that's in the iAdSuite SplitViewBanner example
self.bannerViewController
= [[BannerViewController alloc] initWithContentViewController:splitViewController];
self.window.rootViewController = self.bannerViewController;
i was thus able to use a storyboard UISplitViewController as the childViewController of the BannerViewController provided by iAdSuite.
ok, third caveat: there's one glitch, and that's that if you have the normal bar-button setting via splitViewControllerDelegate set up, the delegate won't get called if you rotate during the ad, and so the button will temporarily show up when it's not supposed to or not show up when it's supposed to.
At first it looks a bit like you forgot to uncomment or implement the shouldAutorotateToInterfaceOrientation variable... But I'm not quite sure. What happens when you tap on the banner? Does it open a new View and an UIWebView or something? Or something else? And when we are talking about AD banners right now, you should probably think about implement Apples iAd Service.

Resources