Use two different nib files for iPhone 4 and iPhone 5 - objective-c

Is there any way to detect what device the user is using, then using that information, make the application use a specific nib file?
Right now, the code that I have is
- (BOOL)application: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions{
if(isiPhone5){
self.RootViewController = #"RootViewController_iPhone5";
}
else{
self.RootViewController = #"RootViewController_iPhone4";
}
}
My other code for finding the device works and tells me what device the user is using, yet doesn't actually change the .xib file from RootViewController_iPhone4.xib to RootViewController_iPhone5.xib. Is there any way to do this?
I don't want to use auto layout, because I would like to have other custom things happen depending upon the device, such as different button names in the view controller if the device being used is an iPhone 4 verses an iPhone 5

Try this way..
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
CGRect screenBounds = [[UIScreen mainScreen] bounds];
if (screenBounds.size.height ==568)
{
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPhone5" bundle:nil];
}
else
{
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPhone4" bundle:nil];
}
Updated Answer
check this...
Black Screen for screen detection

#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
if (IS_IPHONE_5)
{
self = [super initWithNibName:#"YourViewController~iphone5" bundle:nil];
}
else
{
self = [super initWithNibName:#"YourViewController~iphone" bundle:nil];
}
return self;
}
Try something like this

You can achieve this by the following way
create a macro in App delegate so that it will be used through out the Project. It will be based on the screen height for the device.
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 ) < DBL_EPSILON )
Now you can test the condition for iphone 4 and iphone 5
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone){
if(IS_IPHONE_5){
self.window.RootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController_iPhone5" bundle:nil];
}
else
{
self.window.RootViewController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
}
}
}

if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
CGSize result = [[UIScreen mainScreen] bounds].size;
if(result.height == 480)
{
// iPhone 4 Classic
//first always target 4 for better performance & practice.
}
if(result.height == 568)
{
// iPhone 5
}
}else {
//it's ipad
}

Related

Change Orientation on only one View Controller , lock others to portrait mode (xcode 6.2)

I have used the AMSSlideMenuController to create my main VC
#interface LoggedIn_MainVC : AMSlideMenuMainViewController
#end
And In App Delegate I create it using:
//start first vc
self.mainVC = [[LoggedIn_MainVC alloc] init];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
In LoggedIn_MainVC, I create Left and Right Menu both using AMSSlideMenuTableViewController, like so:
#interface LeftMenuVC : AMSlideMenuLeftTableViewController
and they both are instantiated like so in LoggedIn_MainVC:
*******************************/
self.leftMenu = [[LeftMenuVC alloc] initWithNibName:#"LeftMenuVC" bundle:nil];
self.rightMenu = [[RightMenuVC alloc] initWithNibName:#"RightMenuVC" bundle:nil];
/*******************************
In the Left Menu, I have StartPageView, VideoPageView, and SettingsView. I want to lock all other views to portrait mode except for VideoView.
The LeftMenuVC:
#pragma mark - TableView Delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
- {UINavigationController *nvc;
UIViewController *rootVC;
switch (indexPath.row) {
case 0:
{
rootVC = [[VCLoggedIn_StartPage alloc] initWithNibName:#"VCLoggedIn_StartPage" bundle:nil];
}
break;
case 1:
{
rootVC = [[VCLoggedIn_Levels alloc] initWithNibName:#"VCLoggedIn_Levels" bundle:nil];
}
break;
case 2:
{
rootVC = [[VCLoggedIn_Videos alloc] initWithNibName:#"VCLoggedIn_Videos" bundle:nil];
}
break;
case 3:
{
rootVC = [[VCLoggedIn_Settings alloc] initWithNibName:#"VCLoggedIn_Settings" bundle:nil];
}
break;
default:
break;
}
nvc = [[UINavigationController alloc] initWithRootViewController:rootVC];
[self openContentNavigationController:nvc];
}
I am using in Appdelegate
- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
and for videoView:
-(BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger) supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
For OtherViews:
-(BOOL)shouldAutorotate {
return YES;
}
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskPortrait;
}
All the views are behaving equally (both landscape and portrait). however I have found that when I put this orientation mode in LoggedIn_MainVC (the mainView Controller):
- (NSUInteger)supportedInterfaceOrientations{
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
- (BOOL)shouldAutorotate
{
return YES;
}
All the other views are behaving the way this function(supportedInterfaceOrientations) in LoggedInMainVC is defined. When I change to just UIInterfaceOrientationMaskPortrait, all views have only portrait mode and viceversa. Their own definition of supportedInterfaceOrientations is not working.
What am I missing or doing wrong.
Please Help Me
try
- (NSUInteger) application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
return UIInterfaceOrientationMaskLandscape;
}
in videoView to make it landscape

AdMob integration destorts the Hello World Label text

I have created a simple hello world project for cocos2d-x 3.2. Added AdMob banner. The essence of adding banner is to create a view, then add into that view first the cocos2d-x content and then banner content:
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self addChildViewController:_contentController];
[contentView addSubview:_contentController.view];
[_contentController didMoveToParentViewController:self];
[contentView addSubview:_bannerView];
self.view = contentView;
The result is that on iPhone, iPhone Retina, iPad Retina (but not in iPad) the Hello World text is distorted like this:
At the same time that stats text is not distorted:
I cannot understand what happens and why. Here is my full code:
.hfile
#import <UIKit/UIKit.h>
#interface BannerViewController : UIViewController
- (instancetype)initWithContentViewController:(UIViewController *)contentController;
- (void) hideBanner;
- (void) showBanner;
#end
and hers is .mm file
#import "BannerViewController.h"
#import "GADBannerView.h"
#interface BannerViewController () <GADBannerViewDelegate>
#end
#implementation BannerViewController {
GADBannerView *_bannerView;
UIViewController *_contentController;
Boolean _bannerLoaded;
}
- (instancetype)initWithContentViewController:(UIViewController *)contentController
{
self = [super init];
if (self != nil) {
// use kGADAdSizeBanner for a small banner in iPad
_bannerView = [[GADBannerView alloc] initWithAdSize: kGADAdSizeSmartBannerPortrait]; // scaled banner dependent on device size
_bannerView.adUnitID = #"ca-app-pub-874958723945898/8247587858";
_bannerView.delegate = self;
_contentController = contentController;
_bannerLoaded = NO;
}
return self;
}
- (void)loadView
{
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self addChildViewController:_contentController];
[contentView addSubview:_contentController.view];
[_contentController didMoveToParentViewController:self];
[contentView addSubview:_bannerView];
self.view = contentView;
}
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return [_contentController shouldAutorotateToInterfaceOrientation:interfaceOrientation];
}
#endif
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
return [_contentController preferredInterfaceOrientationForPresentation];
}
- (NSUInteger)supportedInterfaceOrientations
{
return [_contentController supportedInterfaceOrientations];
}
// For animation
- (void)viewDidLayoutSubviews
{
CGRect contentFrame = self.view.bounds;
CGRect bannerFrame = CGRectZero;
#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_6_0
bannerFrame = _bannerView.frame;
#else
bannerFrame.size = [_bannerView sizeThatFits:contentFrame.size];
#endif
bannerFrame.origin.x = (contentFrame.size.width - bannerFrame.size.width) / 2;
if (_bannerLoaded) {
//contentFrame.size.height -= bannerFrame.size.height;
bannerFrame.origin.y = contentFrame.size.height - bannerFrame.size.height;
} else {
bannerFrame.origin.y = contentFrame.size.height;
}
_contentController.view.frame = contentFrame;
_bannerView.frame = bannerFrame;
}
- (void)viewDidLoad {
[super viewDidLoad];
_bannerView.rootViewController = self;
[self.view addSubview:_bannerView];
GADRequest *request = [GADRequest request];
[_bannerView loadRequest:request];
}
- (void)adViewDidReceiveAd:(GADBannerView *)bannerView
{
NSLog(#"adViewDidReceiveAd");
_bannerLoaded = YES;
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (void)adView:(GADBannerView *)view didFailToReceiveAdWithError:(GADRequestError *)error
{
NSLog(#"adView didFailToReceiveAdWithError");
_bannerLoaded = NO;
[UIView animateWithDuration:0.25 animations:^{
[self.view setNeedsLayout];
[self.view layoutIfNeeded];
}];
}
- (void) hideBanner{
//TODO:
}
- (void) showBanner{
//TODO:
}
- (void)dealloc {
_bannerView.delegate = nil;
[_bannerView release];
[super dealloc];
}
#end
// </GADBannerViewDelegate>
And I use it in AppController.mm like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
// Add the view controller's view to the window and display.
window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
// Init the CCEAGLView
CCEAGLView *eaglView = [CCEAGLView viewWithFrame: [window bounds]
pixelFormat: kEAGLColorFormatRGBA8
depthFormat: GL_DEPTH24_STENCIL8_OES
preserveBackbuffer: NO
sharegroup: nil
multiSampling: NO
numberOfSamples: 0];
// Use RootViewController manage CCEAGLView
_viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
_viewController.wantsFullScreenLayout = YES;
_viewController.view = eaglView;
_bannerViewController = [[BannerViewController alloc] initWithContentViewController:_viewController];
// Set RootViewController to window
if ( [[UIDevice currentDevice].systemVersion floatValue] < 6.0)
{
// warning: addSubView doesn't work on iOS6
[window addSubview: _bannerViewController.view];
//[window addSubview: _viewController.view];
}
else
{
// use this method on ios6
[window setRootViewController:_bannerViewController];
// [window setRootViewController:_viewController];
}
[window makeKeyAndVisible];
[[UIApplication sharedApplication] setStatusBarHidden:true];
// IMPORTANT: Setting the GLView should be done after creating the RootViewController
cocos2d::GLView *glview = cocos2d::GLView::createWithEAGLView(eaglView);
cocos2d::Director::getInstance()->setOpenGLView(glview);
cocos2d::Application::getInstance()->run();
return YES;
}
What is wrong here?
I have found the problem. I appears that there is a time in hours written with black color like in the image, which on on the Hello World label and hence it distorts:
The time is shown is simulators status bar. In order to hide it I added this:
//fix not hide status on ios7
- (BOOL)prefersStatusBarHidden
{
return YES;
}
into BannerViewController class and that's it!

NSInvalidArgumentException error. Not running under UIUserInterfaceIdiomPad

Whilst I understand why im receiving an error
'', reason: '-[UIPopoverController initWithContentViewController:] called when not running under UIUserInterfaceIdiomPad.'
Rectifying it is becoming a bit tricky. My pop over is only required on the ipad and not on the iphone version. I omitted any code for the iphones if statement and still got a crash. . Presuming that I must call a view on iphone as well as its a universal app, I simply called the nib in the if iphone statement, and that didn't work either.
- (IBAction)popZs:(id)sender {
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
if ([popoverController isPopoverVisible]) {
[popoverController dismissPopoverAnimated:YES];
} else {
[self->popoverController setPopoverContentSize: CGSizeMake(601, 571)];
[popoverController presentPopoverFromRect:((UIButton *)sender).bounds
inView:sender
permittedArrowDirections:UIPopoverArrowDirectionUp
animated:YES];
}
}
else {
/////using iPhone/////not sure how to handle this spart
zsTablePop *pop = [[zsTablePop alloc] init];
pop.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[pop presentModalViewController:pop animated:YES];
}
Keep getting same erorr even though im using if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
creation of pop over
.m
#import "ICCircuitDetails.h"
#import "zsTablePop.h" ///////////////pop over xib/////
#interface ICCircuitDetails ()
{
zsTablePop *controller;
UIPopoverController *popoverController;
}
///////more code/////////////
- (id)initWithCircuit:(Circuit *)circuit
{
self = [super initWithCertificate:circuit.distributionBoard.certificate];
if (self) {
self.circuit = circuit;
[[NSBundle mainBundle] loadNibNamed:#"ICCircuitDetails" owner:self options:nil];
self.view.contentSize = CGSizeMake(self.contentView.frame.size.width, self.contentView.frame.size.height);
///////////other code here/////////////////
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
controller = [[zsTablePop alloc] initWithNibName:#"zsTablePop" bundle:nil];
popoverController = [[UIPopoverController alloc] initWithContentViewController:controller];
Your error message says you try to instantiate a popover. The code only is about presenting it. You need to handle the instantiation as well.

Can't return firstResponder status

Have set up my appDelegate to return a firstResponder status, but when I compile (it compiles fine), the console returns "Could not become the first responder" but doesn't tell why.
I have attached the code. Can you tell me what's wrong? Thanks in advance.
HypnosisterAppDelegate.m
#import "HypnosisterAppDelegate.h"
#import "HypnosisView.h"
#implementation HypnosisterAppDelegate
#synthesize window = _window;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
HypnosisView *view = [[HypnosisView alloc] initWithFrame:[[self window]bounds]];
[[self window]addSubview:view];
BOOL success = [view becomeFirstResponder];
if (success) {
NSLog(#"HypnosisView became the first responder");
} else {
NSLog(#"Could not become the first responder");
}
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
-(BOOL)canBecomeFirstResponder
{
return YES;
}
You've implemented canBecomeFirstResponder on HypnosisterAppDelegate, which is not a UIResponder sub-class. You then send becomeFirstResponder to your custom view (HypnosisView).
HypnosisView (not the HypnosisterAppDelegate) needs to do this:
-(BOOL)canBecomeFirstResponder
{
return YES;
}

BookController in iOS 5 Developer's Cookbook (Erica Sadun) does not start correctly in landscape mode

The problem I'm trying to solve:
I used chapter 05 example 06 BookController in chapter 5 (C05/06-Scrubbing Pages in https://github.com/erica/iOS-5-Cookbook.git ) in a project that have a UInavigatioController as rootViewController, but it does not start correctly in landscape mode. If you rotate the device portrait and return to landscape it begins to work.
To show the bug modify the example test bed delegate in main.c with the following:
#pragma mark Application Setup
#interface TestBedAppDelegate : NSObject <UIApplicationDelegate>
{
UIWindow *window;
}
#end
#implementation TestBedAppDelegate
TestBedViewController *tbvc;
UINavigationController *navigationController;
- (void) pushBookController: (UIGestureRecognizer *) recognizer
{
[navigationController pushViewController:tbvc animated:YES];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
tbvc = [[TestBedViewController alloc] init];
UIViewController *start = [tbvc controllerWithColor:[UIColor whiteColor] withName:#"white"];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(pushBookController:)];
[start.view addGestureRecognizer:tap];
navigationController = [[UINavigationController alloc] initWithRootViewController:start];
window.rootViewController = navigationController;
[window makeKeyAndVisible];
return YES;
}
#end
My application starts landscape, so the problem is that the book controller does not recognize landscape mode at start (if you rotate after start it will work). Try it.
To recognize landscape at start, substitute in BookController the following method
// Entry point for external move request
- (void) moveToPage: (uint) requestedPage
{
//[self fetchControllersForPage:requestedPage orientation:(UIInterfaceOrientation)[UIDevice currentDevice].orientation];
[self fetchControllersForPage:requestedPage orientation:self.interfaceOrientation];
}
and add the following:
- (BOOL) shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation {return YES;}
Now the problem is that BookController does not appear at start, but again if you rotate it begins to work.
probably you solved this already, but try changing the Book's instantiation like this:
+ (id) bookWithDelegate: (id) theDelegate
{
NSDictionary *options = nil;
//Check the orientation
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
//Setting Spine Location to middle for Landscape orientation
options = [NSDictionary dictionaryWithObject:
[NSNumber numberWithInteger:UIPageViewControllerSpineLocationMid]
forKey: UIPageViewControllerOptionSpineLocationKey];
}
BookController *bc = [[BookController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStylePageCurl navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:options];
bc.dataSource = bc;
bc.delegate = bc;
bc.bookDelegate = theDelegate;
return bc;
}
Note that I'm adding a statusBarOrientation check to set the spine.
Basically what you need is to check the orientation when you're creating the UIPageViewController, and I used the statusBarOrientation.
Oh, and don't forget to ensure you're getting the right orientation
- (BOOL) useSideBySide: (UIInterfaceOrientation) orientation
{
BOOL isLandscape = UIInterfaceOrientationIsLandscape(orientation);
// in case the UIInterfaceOrientation is 0.
if (!orientation) {
isLandscape = UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]);
}
return isLandscape;
}
ps: The bookWithDelegate method corresponds to the BookController class within the example mentioned in the question.