I wanna at certain point of the program to load different xib for iphone and for ipad but wanna to reuse most part of the code. how can I achieve this ?
Append ~ipad or ~iphone to the end of the file name. So SomeViewController~ipad.xib or SomeViewController~iphone.xib for instance.
See iOS Supports Device-Specific Resources.
If you create a template project that is universal you can inspect the code created for that version. For Example:
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController_iPhone" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
self.window.rootViewController = self.navigationController;
} else { // iPad
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController_iPad" bundle:nil];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
PSGameViewController *detailViewController = [[PSGameViewController alloc] initWithNibName:#"DetailViewController_iPad" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = [NSArray arrayWithObjects:masterNavigationController, detailNavigationController, nil];
self.window.rootViewController = self.splitViewController;
}
[self.window makeKeyAndVisible];
return YES;
}
or from tableView:didSelectRowAtIndexPath:
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if (self.detailViewController == nil) {
self.detailViewController = [[PSGameViewController alloc] initWithNibName:#"PSGameViewController_iPhone" bundle:nil];
}
self.detailViewController.model = selectedModel;
[self.navigationController pushViewController:self.detailViewController animated:YES];
self.pushedIndexPath = indexPath;
} else { // iPad
self.detailViewController.model = selectedModel;
}
Related
Compiling and running using iOS 7 - getting warning message: "Presenting view controllers on detached view controllers is discouraged" while presenting modal view controller. I have learned that viewcontrollers with linked using the child viewcontroller pattern will not produce warning. Can someone suggest way to link nested viewcontrollers using the child viewcontroller pattern to avoid warning message.
(void)applicationDidFinishLaunching:(UIApplication *)application
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
self.loginRootviewController = [[MainViewController alloc] initWithNibName:#"MainViewController-iPad" bundle:nil];
}
else
{
self.loginRootviewController = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
}
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self.loginRootviewController];
DDMenuController *rootController = [[DDMenuController alloc] initWithRootViewController:navController];
_menuController = rootController;
AppMainMenuViewController *leftController = [[AppMainMenuViewController alloc] init];
rootController.leftViewController = leftController;
self.loginRootviewController.delegateLogin = leftController;
self.window.rootViewController = rootController;
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
}
instead of using DDMenuViewController use SWRevealViewController. It is updated for iOS 7 and has more functionality than DD
I have a strange problem presenting the UIImagePickerController modally in my iOS 6 app. The XCode gives me this error:
Warning: Attempt to present <UIImagePickerController: 0x1e025040> on <UINavigationController: 0x1d51ce00> whose view is not in the window hierarchy!
I have the following window hierarchy in my AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIWindow *window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window = window;
firstViewController = [[SGNewMailViewController alloc] init];
navController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
self.window.rootViewController = firstViewController;
[self.window makeKeyAndVisible];
return YES;
}
In my SGNewMailViewController I present a new UIView, a member of SGFoldingAttachmentView class which has this code in it:
- (void)choosePhotoPressed {
SGNewMailViewController *mailVC = [((SGAppDelegate *)[UIApplication sharedApplication].delegate).firstViewController.navigationController.viewControllers lastObject];
[mailVC displayCameraRoll];
}
In the end, here's my SGNewMailViewController displayCameraRoll method:
- (void)displayCameraRoll {
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeSavedPhotosAlbum])
{
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType =
UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = [NSArray arrayWithObjects:
(NSString *) kUTTypeImage,
nil];
imagePicker.allowsEditing = NO;
[self presentViewController:imagePicker animated:YES completion:nil];
}
}
So what can possibly be the problem? Is it in the custom view presented from another class? How should I fix it? Thanks in advance!
Make the UINavigationController to be the root view controller of your window. This should fix the problem
self.window.rootViewController = navController;
I implemented Tab bar controller in my app. But my first page is Login View. So, i don't want to show tab bar on it. I did this by hiding the tab bar on that view.
But Now, When i selected the First tab , it always goes to the rootview controller as a Login Page.
//for home tab..
UINavigationController *nav1 = [[UINavigationController alloc] init];
UIViewController *viewController1;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController1 = [[[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil] autorelease];
} else
{
viewController1 = [[[LoginViewController alloc] initWithNibName:#"LoginViewController_iPad" bundle:nil] autorelease];
}
nav1.viewControllers = [NSArray arrayWithObjects:viewController1, nil];
//for account tab...
UINavigationController *nav2 = [[UINavigationController alloc] init];
UIViewController *viewController2;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController2 = [[[AccountView alloc] initWithNibName:#"AccountView_iPhone" bundle:nil] autorelease];
} else
{
viewController2 = [[[AccountView alloc] initWithNibName:#"AccountView_iPad" bundle:nil] autorelease];
}
nav2.viewControllers = [NSArray arrayWithObjects:viewController2, nil];
//for links tab...
UINavigationController *nav3 = [[UINavigationController alloc] init];
UIViewController *viewController3;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController3 = [[[LinksView alloc] initWithNibName:#"LinksView_iPhone" bundle:nil] autorelease];
} else
{
viewController3 = [[[LinksView alloc] initWithNibName:#"LinksView_iPad" bundle:nil] autorelease];
}
nav3.viewControllers = [NSArray arrayWithObjects:viewController3, nil];
//for about us tab...
UINavigationController *nav4 = [[UINavigationController alloc] init];
UIViewController *viewController4;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController4 = [[[AboutUsView alloc] initWithNibName:#"AboutUsView_iPhone" bundle:nil] autorelease];
} else
{
viewController4 = [[[AboutUsView alloc] initWithNibName:#"AboutUsView_iPad" bundle:nil] autorelease];
}
nav4.viewControllers = [NSArray arrayWithObjects:viewController4, nil];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:nav1,nav2,nav3,nav4,nil];
self.tabBarController.tabBar.tintColor = [UIColor blackColor];
//self.tabBarController.tabBar.tintColor = [UIColor colorWithRed:237.0/255.0 green:208.0/255.0 blue:0.0/255.0 alpha:1.0];
self.window.rootViewController=self.tabBarController;
How can i solve this?
just assign the viewController mto the UINavigationController like bellow.
UINavigationController *nav1 =[[UINavigationController alloc]initWithRootViewController:viewController1];
UINavigationController *nav2 =[[UINavigationController alloc]initWithRootViewController:viewController2];
UINavigationController *nav3 =[[UINavigationController alloc]initWithRootViewController:viewController3];
UINavigationController *nav4 =[[UINavigationController alloc]initWithRootViewController:viewController4];
and then assign in tabbar same like your code..
self.tabBarController.viewControllers = [NSArray arrayWithObjects:nav1,nav2,nav3,nav4,nil];
self.window.rootViewController = self.tabBarController;
Take a look at this solution.
Basically you could switch the rootViewController from your loginVC to the tabBarVC after the user has logged. But i think that the loginVC should not be the "first page" of you tabBarVC but shuold be an indipendent viewController.
But if you want anyway the login in the first tab you can just change the view of the VC after the user has logged.
You can set a flag in NSUserDefaults to know if the user has logged so in the viewDidAppear: of the first tab you can check if the user is logged and show your different UI.
ps: you can find a little trick to not write all the conditions to load a different xib for iPhone/iPad here.
You have to use a different way to show your Loginview without tabBarController
Don't use LoginView on tabBarController.
You have to choose a boolean value like login.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSUserDefaults *default=[NSUserDefaults standardUserDefaults];
if(![default boolForKey:#"login"])
{
//here tab is your tabBarController.
[tab presentViewController:yourLoginView animated:YES completion:nil];
}
else{
//your normal code
}
After User login you can set login=YES.
Good day. I try to add new tab with navigation controller to my app. I create a new tabbed app (xcode 4.2) and in appdelegate write this
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1 = [[[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil] autorelease];
UIViewController *viewController2 = [[[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil] autorelease];
NavController *navController = [[[NavController alloc] initWithNibName:#"NavController" bundle:nil] autorelease]; //my controller
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, navController, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
NavController.h file
#interface NavController : UINavigationController
#end
Here the structure of project
And when I run project it show me empty tab
But in xib file I add lable and buttons
May be I forgot something?
Initialise your navigation controller with some UIViewController that is :
RootViewController *rootViewController = [[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil] autorelease];
NavController *navController = [[[NavController alloc] initWithRootViewController: rootViewController] autorelease];
This might help.
i am sharing you my APP Code about this feature,Hope this can solve your Problem easily
Add this code in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
UINavigationController *localNavigationController;
tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:3];
viewController = [[[ViewController alloc] initWithNibName:#"ViewController" bundle:nil] autorelease];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
[localControllersArray addObject:localNavigationController];
AlaramClock *aAlaramClock = [[[AlaramClock alloc] initWithNibName:#"AlaramClock" bundle:nil] autorelease];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:aAlaramClock];
[localControllersArray addObject:localNavigationController];
CurrentTime *aCurrentTime = [[[CurrentTime alloc] initWithNibName:#"CurrentTime" bundle:nil] autorelease];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:aCurrentTime];
[localControllersArray addObject:localNavigationController];
Settings *aSettings = [[[Settings alloc] initWithNibName:#"Settings" bundle:nil] autorelease];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:aSettings];
[localControllersArray addObject:localNavigationController];
tabBarController.viewControllers = localControllersArray;
[localControllersArray release];
// Override point for customization after app launch
[window addSubview:tabBarController.view];
[window makeKeyAndVisible];
return YES;
}
Then U will get this look
after this in Every ViewController.m
ADD this
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])
{
// Custom initialization
self.title=#"Calculate Time";
self.tabBarItem.title = #"Calculate Time";
self.tabBarItem.image=[UIImage imageNamed:#"time_calculate.png"];
}
return self;
}
As this configuration is not supported I was wondering what alternatives people have used.
I have a universal app which currently uses a 4 tab UITabBarController on both the iPhone and iPad.
As I'd now like to use the splitviewcontroller I am faced with a design decision.
I guess I could just go with a toolbar at the top and go from there but was hoping there were more interesting techniques.
You could replicate a UITabBar within a modelViewController that pops up when a button on the bottom of the screen is taped and swap Views. :)
I created a UITabBarController subclass which properly propagates the rotation messages to all UISplitViewControllers it contains. This maintains the correct internal state of the UISplitViewControllers. However, one of the SplitViewController delegate methods is not called if the SplitViewController is not visible, so I account for this in the detail view controller viewWillAppear method. I've confirmed this works in iOS5.0 - iOS6.1
AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
OSMasterViewController *masterViewController = [[[OSMasterViewController alloc] initWithNibName:#"OSMasterViewController_iPhone" bundle:nil] autorelease];
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];
self.window.rootViewController = self.navigationController;
} else {
OSMasterViewController *masterViewController = [[[OSMasterViewController alloc] initWithNibName:#"OSMasterViewController_iPad" bundle:nil] autorelease];
UINavigationController *masterNavigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];
OSDetailViewController *detailViewController = [[[OSDetailViewController alloc] initWithNibName:#"OSDetailViewController_iPad" bundle:nil] autorelease];
UINavigationController *detailNavigationController = [[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];
masterViewController.detailViewController = detailViewController;
UISplitViewController *splitViewController = [[[OSSplitViewController alloc] init] autorelease];
splitViewController.viewControllers = #[masterNavigationController, detailNavigationController];
splitViewController.delegate = detailViewController;
OSTestViewController *secondaryController = [[[OSTestViewController alloc] init] autorelease];
OSTabBarController *tabBarController = [[[OSTabBarController alloc] init] autorelease];
tabBarController.viewControllers = #[self.splitViewController, secondaryController];
self.window.rootViewController = tabBarController;
}
[self.window makeKeyAndVisible];
return YES;
}
OSTabBarController.m
#import "OSTabBarController.h"
#implementation OSTabBarController
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration{
[super willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
for(UIViewController *targetController in self.viewControllers){
if(targetController != self.selectedViewController && [targetController isKindOfClass:[UISplitViewController class]]){
[targetController willRotateToInterfaceOrientation:toInterfaceOrientation duration:duration];
}
}
}
-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
[super didRotateFromInterfaceOrientation:fromInterfaceOrientation];
for(UIViewController *targetController in self.viewControllers){
if(targetController != self.selectedViewController && [targetController isKindOfClass:[UISplitViewController class]]){
[targetController didRotateFromInterfaceOrientation:fromInterfaceOrientation];
}
}
}
#end
DetailViewController
#implementation OSDetailViewController
-(void)viewWillAppear:(BOOL)animated{
//the splitViewController:willHideViewController:withBarButtonItem:forPopoverController: may not have been called
if(!UIInterfaceOrientationIsPortrait(self.interfaceOrientation)){
self.navigationItem.leftBarButtonItem = nil;
}
}
#pragma mark - UISplitViewControllerDelegate Methods
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
[self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
}
- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
}
#end