upgrading iPhone app to universal and now using splitview - iphone

I have an iPhone app that works and is getting used. I now want to upgrade this application to a Universal app. Taking that into consideration I've already made changes, like creating another MainWindow.xib for the iPad, which i've gotten to work. I've pretty much got the whole iPhone App working for the iPad. The next step I needed to take was to convert my Events Calendar to be a splitview. As far as I can tell, I'm don't need to change any of the logic in the two controllers I already have (CalendarViewController and CalendarDetailViewController).
That being said, what is the best way to make them work on a splitview? Is it possible to have the splitview use these two controllers (since a splitview has two controllers by default, a TableViewController and a ViewController)? Would I then need to create another appDelegate or something to pass all the right information back to the MainWindow.xib? Or am I going to need to create a new SplitViewController? and if so, how would I then combine all the logic from my two Calendar Controllers?
Any help would be greatly appreciated!!

Assuming you are using StoryBoard: drag a SplitViewController into the iPad StoryBoard. Also be sure your two desired UIViewControllers are in there. Control-click on the SplitViewController and drag over to each UIViewController and select you how want it set.

I know it's a bit late to answer this question but if someone needs...
You don´t need another appDelegate, you just need to check (in appDelegate) whether your device is an iPad, and then set an array of view Controllers with the MasterVC and the DetailVC. Otherwise you will set your rootViewController as you are doing now in the iPhone app.
It would be something similar to that:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[...]
YourMasterVC *mvc =
[[YourMasterVC alloc] initWithStyle:UITableViewStylePlain];
UINavigationController *masterNav =
[[UINavigationController alloc] initWithRootViewController:mvc];
YourDetailVC *dvc = [[YourDetailVC alloc] init];
cvc.detailViewController = dvc;
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) {
// On iPad
UINavigationController *detailNav =
[[UINavigationController alloc] initWithRootViewController:dvc];
UISplitViewController *svc = [[UISplitViewController alloc] init];
svc.delegate = wvc;
svc.viewControllers = #[masterNav, detailNav];
self.window.rootViewController = svc;
} else {
// On iPhone
self.window.rootViewController = masterNav;
}
[...]
}

Related

Auto-resize iPhone xib app to ipad

I built an iPhone app "using xib" with 5-6 screens. Now I want to auto-resize the display for iPad. I am using xcode 4.6.
Do I have to rebuild the entire code using storyboards? It will be a very tedious work. Is there any solution for this?
You'll need to create only new xib files for iPad and name them as ViewController_iPhone.xib and ViewController_iPad.xib and when switching your views, just put a simple condition
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
ViewController *viewController = [[ViewController alloc] initWithNibName:
#"ViewController_iPad" bundle:nil];
} else {
ViewController *viewController = [[ViewController alloc] initWithNibName:
#"ViewController_iPhone" bundle:nil];
}
use autolayout and everything will be done automatically
if not autolayout, then making 2 xib will be a better option. Make ipad size xib with the same name and put ~ipad after classname.
Like if you xib name is myClass.xib and create other one like myClass~ipad.xib.

App wont start using testflight on iOS6

I have an application that I want to test it on iOS device. The application uses NIB files and no story board.
Target framework is set to - 5.1
Device - Universal.
I have created the IPA file and uploaded to TestFlightApp.
I have downloaded and installed the application on my iPad. Weird thing is when I tap on the icon a black screen shows and nothing else happens.
I have done the following settings.
Main Interface - SSDMainViewController
Main Storyboard - Not set as I don't have any storyboard in the applicaion.
It is not the problem of IOS versions as other apps are working fine.
EDIT : When I double click the iPad button I saw that the application
is not crashing. It is running in the background.
EDIT 2 : More information on the question.
Well I have taken a view based application and it has all NIBs no storyboard. It was initially an iPhone application targeting the IOS 5.1 but then I have changed the value from the project drop down to UNIVERSAL. But that I think is no problem because when I installed it in my iPad it showed me nothing. Also it showed black screen with the iPhone frame and then nothing. The application is still live in the thread.
What bothers me is that I have done this in the AppDelegate :
I have set the
self.mainViewController = [[SSDMainViewController alloc] initwithnibname:#"SSDMainViewController" bundle:nil];
And then I have set the navigation controller and then pushed the view to it.
I FOUND SOME MORE INFORMATION
In the console it says.
The application is expected to have its root view set at the end of application start.
MY APP DELEGATE
ftipValue=0.25;
cardtype = #"American Express";
[cardtype retain];
[self CallFunctionForLogout];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Create an instance of YourViewController
//SSDMainViewController *yourViewController = [[SSDMainViewController alloc] init];
self.mainViewController = [[[SSDMainViewController alloc] initWithNibName:#"SSDMainViewController" bundle:nil] autorelease];
// Create an instance of a UINavigationController
// its stack contains only yourViewController
UINavigationController *navController = [[UINavigationController alloc]
initWithRootViewController:self.mainViewController];
navController.navigationBarHidden = YES;
// Place navigation controller's view in the window hierarchy
[[self window] setRootViewController:navController];
[self.window makeKeyAndVisible];
return YES;
Please use two xib file, universal app we want two xib (nib)
one for iPhone - ViewController_iPhone
second for for iPad - ViewController_iPad
Add following code to your AppDelegate.m file.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil] autorelease];
}
else {
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil] autorelease];
}
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
I have done this and it's work fine for me.
That error means that you're not setting up your application correctly.
You say you've set SSDMainController as the main interface file - is this both for iPhone and iPad? There are two sets of entries in that section of the summary tab for universal apps.
I would expect a different xib file to be specified for the iPad, since a different sized view and different layout would be in use.
You have either not set the iPad xib, so the app can't set up a window with root view controller, or you haven't set up a valid iPad xib, so it isn't loading at all, with the same results.
If you just want the app to run in the mini-iPhone window with the 2x button, leave it as an iPhone only app.
If you are getting "The application is expected to have its root view set at the end of application start." there are a number of possibilities. Clearly, that is the problem, since you have a black screen with nothing in it...
Check out this SO question: Application windows are expected to have a root view controller at the end of application launch warning Rob Mayoff has a good description of what should be happening when your application initializes.
Also, linked to in the above post, is this post wherein there are an additional 35 answers with various scenarios of what could be happening.
Beyond browsing through those links, you will need to post up additional code and/or descriptions of how your nibs are wired up for anyone to help you--as evidenced by the myriad ways it is possible to cripple the initialization sequence.

App doesn't rotate on iPhone Simulator

I'm wanting to test out my app with the iPhone 5 resolution, so I'm using the simulator. My app has Portrait and 2 landscape orientations in Supported Device Orientations, and the viewControllers which allow rotation have shouldAutorotateToInterfaceOrientation set to YES. Yet when I rotate the device in the simulator, it doesn't rotate as it does on the device. Right now i'm just using the standard iPhone 4 simulator.
Edit: This is the code I have for setting my VC.
UIViewController *vc = [[UIViewController alloc] init];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:vc];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
[self.window addSubview:self.navigationController.view];
self.loadingWood = [[UIImageView alloc] init];
[vc.view addSubview:self.loadingWood];
And then shortly after:
self.timeline = [[JTimelineViewController alloc] init];
[self.navigationController setViewControllers:[NSArray arrayWithObject:self.timeline]];
This is necessary for visuals when the app starts up.
EDIT 2:
I now have this working. The problem I now face is that despite one of my viewControllers stating this, it still rotates upon any rotation on the iPhone Simulator:
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
EDIT 3: My phone is running iOS5. The simulator is running iOS6. This is a possible reason. Removing Landscape Left and Landscape Right as supported orientations means no simulator rotation at all, but my iOS5 iPhone 4 continues to rotate as normal.
Make sure that you're setting the root view controller, as in:
self.window.rootViewController = self.navigationController;
I had to deal with something similar in the past. What's going in is that only the main view controller of the application receives the rotation notifications and delegate calls. There are some exceptions, like the UINavigationController, that passes down those events to their current view controller.
So, for example, if your AppDelegate class loads a view controller and that view controller pushes a second view controller, that second view controller will not receive the rotation notifications.
I recommend you use a UINavigationController to push your UIViewControllers onto the display, since UINavigationController passes down the rotation delegate calls and notifications.
EDIT
In Xcode's preference, under the Download tab, you have the option of downloading previous simulators, iOS 5 and iOS 5.1. Download those and set your target iOS version to 5.0 (or 5.1) and select the correct simulator from the device list. See if you get the same problem as with the iOS 6 simulator. If you get that, than there's definitely a difference between iOS 5 and iOS 6's way of handling UINavs.
Also, using the difference between setViewControllers and pushViewController is that pushViewController adds the view controller as a child of the parent view controller, which makes it respond to the delegate calls, including rotation. Since iOS 5, every UIViewController now has a method called addChildViewController that gives that functionality to the UIViewController class.

objective-c : How to move from AppDelegate in Universal app?

I am developing a Universal app where I have
imageTracker_iPhone.xib
imageTracker_iPad.xib
imageTracker.h
imageTracker.m
I want to move from AppDelegate_iPhone to imageTracker. I am doing this in didFinishLaunchingWithOptions but its not working before this code I was using
imageTracker *vRDi = [[imageTracker alloc] initWithNibName:#"imageTracker_iPhone" bundle:nil];
[self.view addSubview:vRDi.view];
but it gave error request for member 'view' in something not a structure or union
. Even if code is like
[window addSubview:vRDi.view];
now The function is like below and its not working. I want to move from AppDeligate to imageTracker. please help
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window addSubview:imageTracker.view];
[self.window makeKeyAndVisible];
return YES;
}
In this case It does not move to imageTracker_iPhone because did not tell any where to move to this file, so want to know that HOw to tell that which file to move either imageTracker_iPhone or imageTracker_iPad.
You probably want to set the delegate window's rootViewController to make your first controller active. (If you create a new test app from a single controller, non-storyboard template, you can see the kind of code that's needed in didFinishLaunchingWithOptions:.)
Edit: Actually, it's even easier than that. If you specify a universal app when creating a single view controller project, it creates the exact code to test which kind of device and load the matching .xib file. (Xcode 4.2, at least.)
your code should be something like this
imageTracker *vRDi;
Bool isiPhone = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone;
if(isiPhone)
vRDi = [[imageTracker alloc] initWithNibName:#"imageTracker_iPhone";
else
vRDi = [[imageTracker alloc] initWithNibName:#"imageTracker_iPad";
and make sure that your connect view outlet in both xib's and the file owner is "imageTracker" Class.

How can I load firmware dependent NIBS?

Here is my question :
I have an app running smoothly on iOS 3.0
I've been working a long time to port it to 4.0 and to include the new features.
I added iAds using Interface Builder.
I know that I have to define it programmatically to still support 3.0 devices.
I weak linked the framework. But the app crashes when loading the NIB.
Is there a way to load NIB's depending on the firmware version ?
Let's say I have FirstView.xib and FirstView3X.xib
How can I choose which one will be loaded depending on the firmware ?
Thanks
PS: It's my first question on StackOverflow !
Congratulations to your first question :-) How do you load the nibs? It’s a good idea to split the interface into several files. I usually use a separate nib per every controller and load them using the initWithNibName:bundle: initializer. Since you supply the nib name here, you could easily customize the loading behaviour.
If you load the nibs using the tab bar controller, you probably have all the tabs in one nib. I think I would break the tabs into separate nibs and load them programmatically:
id tab1 = [[UIViewController alloc] initWithNibName:#"Tab1" bundle:nil];
id tab2 = [[UIViewController alloc] initWithNibName:#"Tab2" bundle:nil];
id tab3 = [[UIViewController alloc] initWithNibName:#"Tab3" bundle:nil];
[tabBarController setViewControllers:[NSArray arrayWithObjects:
tab1, tab2, tab3, nil]];
And since you would now have the control over the nib names, you could easily detect the firmware version and load the correct nib:
id tab1 = [[UIViewController alloc] initWithNibName:
[self nibNameForCurrentFirmware] bundle:nil];
As for the firmware version detection itself, I think you could use [UIDevice systemVersion].
You can pull the current version from the UIDevice object:
NSString *osVersion = [[UIDevice currentDevice]systemVersion];
NSArray *ver = [osVersion componentsSeparatedByString:#"."];
If you're happy with comparing strings for single values (e.g. [[ver objectAtIndex:0] isEqualToString:#"3"]). You might want to convert the version numbers to integers so you can compare them for range (e.g., osMajor >= 4).
You can also check for certain classes to exist and load the appropriate NIB based on that:
if (NSClassFromString(#"MKMapView") != nil) {
/* Do map stuff... */
}