iOS: Universal App Template supporting iAds & screen rotations - iphone

I am trying to construct a iOS universal application template that transparently handles iAds & screen rotations.
i.e. instead of using UIViewController for each new project, I will instead use my own iAdVC (which will subclass UIViewController). This will seamlessly handle the iAds, and hand over the remaining window space to the user.
I'm trying this: view controller contains uberView which contains {adView, content view}.
whenever an ad appears and disappears, both {adView, content view} will animate:
content view squashing the frame's top down slightly to make space for my iAd,
and fade in the ad along the top at the same time.
also, every time the device rotates, the views need to be resized.
I'm getting really dumb problem, when the first Ad gets served, I place it at the top of the screen and squash the remaining content frame to make space for it.
but if I change the content view's frame, I can no longer click the ad. and if I don't, the content view doesn't fit in its window,
http://d.pr/ZyQG
- (void) bannerViewDidLoadAd: (ADBannerView *) banner
{
bool isLandscape = UIInterfaceOrientationIsLandscape( self.interfaceOrientation );
NSString * contentSize = isLandscape ? ADBannerContentSizeIdentifierLandscape : ADBannerContentSizeIdentifierPortrait ;
[self.adBannerView setCurrentContentSizeIdentifier: contentSize];
CGSize bannerSize = [ADBannerView sizeFromBannerContentSizeIdentifier: contentSize];
self.adBannerView.frame = CGRectMake(0, 0, bannerSize.width, bannerSize.height);
// resize content frame & fade ad in
CGRect newContentFrame = uberView.bounds;
newContentFrame.size.height -= bannerSize.height;
newContentFrame.origin.y += bannerSize.height;
NSLog(#"%#", NSStringFromCGRect(newContentFrame)); // {{0, 50}, {320, 430}}
if (1) // 0 works
self.contentView.frame = newContentFrame; // NOW CANT CLICK AD
}

Minimum deployment target
The first question is: what is a sensible minimum deployment target? Seeing as this is a universal application, we should use iOS 4.2, as this is the first version that is unified between iPhone and iPad.
Question arises: what fraction of ad-clicking customers do we lose? eg is it worth supporting 4.0 just to get an extra 15% of customers?
http://insights.chitika.com/2011/ios-update-ipads-iphones-running-high-rate-of-ios-4/ shows that you still pick up 80% of ad-clicking customers if you select 4.2.
Obviously this fraction is going to increase with time, so I'm going for the easiest coding option rather than trying to squeeze every last penny out of the market.
This has an added benefit:
// Supported sizes of banner ads available from ad server. Dimensions are in points, not pixels.
// The dimensions are part of the value names to assist with design-time planning for view layout.
extern NSString * const ADBannerContentSizeIdentifier320x50 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA,__MAC_NA,__IPHONE_4_0,__IPHONE_4_2);
extern NSString * const ADBannerContentSizeIdentifier480x32 __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_NA,__MAC_NA,__IPHONE_4_0,__IPHONE_4_2);
extern NSString * const ADBannerContentSizeIdentifierPortrait __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_2);
extern NSString * const ADBannerContentSizeIdentifierLandscape __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_4_2);
ie We can use the new symbols, which are generic (ie work for both iPhone and iPad)
strPortrait = ADBannerContentSizeIdentifierPortrait; // ADBannerContentSizeIdentifier320x50;
strLandscape = ADBannerContentSizeIdentifierLandscape; // ADBannerContentSizeIdentifier480x32;
The banner can be either horizontal or vertical, so you need to load in:
[self.adBannerView setRequiredContentSizeIdentifiers:
[NSSet setWithObjects: strPortrait, strLandscape, nil]
];
Then when the screen turns 90°, the AdBannerView needs to be told:
[self.adBannerView setCurrentContentSizeIdentifier: isLandscape ? strLandscape : strPortrait ];
Directly after this is set, you can query self.adBannerView.frame and get the new size

https://github.com/p-i-/iAdUniversalTemplate
This is a XIB-less universal-app iAd-rotatey-enabled template, which requires a minimum target of iOS 4.2
It took a lot of thrashing around, namely iAd -- cannot click banner
But it is in good shape now.

Related

How to use the area around Macbook's notch in fullscreen?

I need to use the area around (and behind) the notch while application is in full screen mode and display my app "fully full-screen" and use that area to display elements, as if there is no notch there.
I understand that is where the menu bar appears, but I am okay with either disabling menu bar in full screen OR making it act like older macs when it would appear over the application after we move cursor higher in that area.
I've tried (to no avail):
Playing with Safe Area
Hiding Title Bar from inspection menu in Xcode
Removing the Menu completely
Adding UISupportsTrueScreenSizeOnMac = true to plist
P.S. I've already done hours of searching on Google and SO, as well as Apple's documentation but haven't found any indication of how to achieve this.
I do not think you can use fullscreen mode to do this, because there is no public API for overriding your window's fullscreen frame to include the unsafe areas around the sensor housing (the ‘notch’).
You should be able to manually achieve this by looking at the NSScreen representing the built-in display. Set your window's frame to the screen's frame (not the screen's visibleFrame). The screen's auxiliaryTopLeftArea and auxiliaryTopRightArea describe the areas to the left and right of the notch. From those, you can deduce the area obscured by the notch.
This is how I managed to achieve this (simplified just for reference):
Hide application's "Title Bar"
Set your window's frame to full width and height on load (again, simplified)
override func windowDidLoad() {
window!.setFrame(CGRect(x: 0, y: 0, width: NSScreen.main!.frame.width, height: NSScreen.main!.frame.height), display: true)
}
Set LSUIPresentationMode in your plist
<key>LSUIPresentationMode</key>
<integer>3</integer> // Change this to 4 if you want to allow menu bar and dock to appear when user moves cursor top/bottom edges (they are initially hidden)
Note:
Without using LSUIPresentationMode or even hiding title bar, the following code would launch the app in fullscreen and for ~1 second it would fill the area around notch as well, but then it would revert back to the area below notch.
Just thought I should also mention this, so there might be ways to achieve this while using native fullscreen
window!.toggleFullScreen(self)
window!.setFrame(CGRect(x: 0, y: 0, width: 1728, height: 1117), display: true)
This is not a solution. But maybe helpful.
I tried swizzling -[_NSFullScreenContentController reservesSpaceForMenuBarInFullScreen] with retuning value NO.
#import <Cocoa/Cocoa.h>
#import <objc/message.h>
void swizzle(Class class, SEL cmd, IMP custom, IMP _Nullable * _Nullable original) {
Method originalMethod = class_getInstanceMethod(class, cmd);
IMP originalImp = method_getImplementation(originalMethod);
*original = originalImp;
class_replaceMethod(class, cmd, custom, nil);
}
BOOL (*original_NSFullScreenContentController_reservesSpaceForMenuBarInFullScreen)(id, SEL);
BOOL custom_NSFullScreenContentController_reservesSpaceForMenuBarInFullScreen(id self, SEL cmd) {
return NO;
}
#implementation NSWindow (Swizzle)
+ (void)load {
swizzle(NSClassFromString(#"_NSFullScreenContentController"), NSSelectorFromString(#"reservesSpaceForMenuBarInFullScreen"), (IMP)&custom_NSFullScreenContentController_reservesSpaceForMenuBarInFullScreen, (IMP *)&original_NSFullScreenContentController_reservesSpaceForMenuBarInFullScreen);
}
#end
Here's the results.
Before
After
With swizzling -[_NSFullScreenContentController reservesSpaceForMenuBarInFullScreen] frame of window will be fit to screen. But I cannot find how to remove a black bar.

How to make xib compatible with both iphone 5 and iphone 4 devices

I am trying to layout my xib so that layout fits in both iphone 5 (4 inches retina) and 3.5 devices.
Because I have to support IOS-5 I cannot use autolayout. I have to use springs and Struts.
I tried everything in interface-builder. But either my view is going beyond the bottom of iphone-3.5-inch or not filling completely the iphone-4-inch-retina.
Can someone give a hint how to actually make an xib compatible to both the devices?
For more clarity I am adding screenshots:
When I set size 3.5 in attribute inspector:
it looks in iphone-5. There is a space below the buttons:
If I set size 4 inch in interface builder. You can see that bottom buttons are not visible in iphone-4.
So you will ask what are the settings I am using. Here are they:
You add new category for UIviewController and add this code in .h file
- (id)initWithNibNameforIphone4:(NSString *)nibNameOrNil4 NibNameforIphone5:(NSString *)nibNameOrNil5 NibNameforIpad:(NSString *)nibNameOrNilpad bundle:(NSBundle *)nibBundleOrNil;
Add this code in your .m file
- (id)initWithNibNameforIphone4:(NSString *)nibNameOrNil4 NibNameforIphone5:(NSString *)nibNameOrNil5 NibNameforIpad:(NSString *)nibNameOrNilpad bundle:(NSBundle *)nibBundleOrNil
{
if (self = [super init])
{
self = [self initWithNibName:[self CheckDeviceIphone4:nibNameOrNil4 Iphone5:nibNameOrNil5 Ipad:nibNameOrNilpad] bundle:nibBundleOrNil];
}
return self;
}
-(NSString *)CheckDeviceIphone4:(NSString *)iphone4 Iphone5:(NSString *)iphone5 Ipad:(NSString *)ipad {
return ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad) ? ipad :([[UIScreen mainScreen] bounds].size.height == 568) ? iphone5 :iphone4;
}
Open YouProject-Prefix.pch file and import your category here
now you just use this in all over project like this
self.firstView=[[firstView alloc]initWithNibNameforIphone4:#"firstView4" NibNameforIphone5:#"firstView" NibNameforIpad:#"firstViewIpad" bundle:[NSBundle mainBundle]];
thanks and any question then comment and dont forget to upvote :-)
\
Try adding this to all your controllers which need to support iPhone 5:
- (void) loadView
{
[super loadView];
self.view.frame = [UIScreen mainScreen].bounds;
}
Just set view size to None using Interface-builder
It will take view size at runtime, just you need to take care of origin and autosizing for each element(UILabel, UIImage, etc.) in the view.
Interface-builder(XIB) -> Attribute Inspector -> Simulated Metrics - Size: None
I was struggling with this today, and no matter what I did, my views were always showing up as 320x480, even when running on the retina 4" simulator. Even [UIScreen mainScreen].bounds was returning 320x480!
I found that adding the Default-568h#2x.png launch image was the key to getting iOS to recognize my app as 'retina 4" ready'. Once I did that, I found had to do nothing else to get nibs to automatically size without the black bars. No need to have two separate xibs, change settings in Interface Builder, overriding loadView, etc.
You need not use a different nib for the 3.5 inch and 4 inch devices. Design the app for the 4 inch device and set the AutoResizingMask correctly and it should work correctly.
In your case just set the AutoResizingMask to
[view setAutoresizingMask:UIViewAutoresizingFlexibleTopMargin|UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth];
The autoresizing mask places the view correctly to its position in both the devices.
If you go with the solution of using 2 xib files; in your initWithNibName() method simply make a call to super with the different nib name.
I would test on the original 480 height dimension rather than on the 568 height so that the larger xib file is selected when Apple releases a larger screen. In the future, at least the larger xib won't be letter-boxed as much as the smaller one.
// From MainView.m
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
CGSize result = [[UIScreen mainScreen] bounds].size;
if(result.height == 480)
{
// iPhone Classic
self = [super initWithNibName:#"MainView" bundle:nibBundleOrNil];
}
else
{
// iPhone 5 or maybe a larger iPhone ??
self = [super initWithNibName:#"MainView5" bundle:nibBundleOrNil];
}
return self;
}
I have an idea. Let separate your UI into header, body and footer (like website). Then in your code console, locate to Size Inspector and use the Autosizing.
Notice the outside lines of the square, it is your control location against main view. Set the controls (navigation bar, UIImageView, UIButton etc.) in header part and body part attached to Top and the controls (Bookmark, Close etc.) in footer to Bottom.
Everytime you run, the controls will attach to their autosizing settings. You will have a space between header/body and footer on iPhone 5 but I think it's fine.
Define below line and check condition based on device.
#define IS_IPHONE_5 ( fabs( ( double )[ [ UIScreen mainScreen ] bounds ].size.height - ( double )568 )
if (IS_IPHONE_5) {
btnBookmark.frame=CGRectMake(0, 460, 100, 70);
btnBookmark.frame=CGRectMake(150, 460, 100, 70);
}
else {
btnBookmark.frame=CGRectMake(0, 360, 100, 70);
btnBookmark.frame=CGRectMake(150, 360, 100, 70);
}
I was having an issue with 3.5" vs. 4" as well, and I misunderstood what was wrong so I wanted to document it here incase it helps anyone.
If you are trying to access self.view.frame it will not be correctly reported until viewDidAppear or some similar event. If you try to access self.view.frame from within viewDidLoad then you can be reported the dimensions of the frame before autosizing takes place.
In your storyboard, click 'Show file inspector'.
Under Interface builder document->Document versioning, select Deployment=iOS 5 (or your choice).
If this doesn't work, you need to work with each of your views.
Select them. Under Attributes inspector for each of them, under View section, see Mode attribute. Set this to 'Redraw'.
If even that doesn't give satisfactory result, set the view size to the smallest of all the version you are going to use. And set the Mode attribute = 'Scale to fill'.
Programmatically, Mode attribute is view.contentmode property.
Without using autolayout you may need to handle a lot of things in code. I assume most of your layout can work well with springs and struts but some UI elements can't so just manually set the frames of certain objects according to the size of your view is necessary.
ivanzoid's snippet above that queries for the whole screen size does the trick so long as you remember to subtract the offsets for navigation and toolbars (totalling 64 under most conditions).
It's the view height that needs to be adjusted; springs and struts otherwise take care of it.
Retesting my app on the iPhone 5 I only had to do this on one screen with some runtime control position adjustments. Every other case is handled by XIB defaults.
If you dont want use two xib and interested to do using Autosizing here
If your UI is too complicated and contains too many UIControls , then I suggest to do the following in viewDidLoad():
NSLog(#"Iphone %f ",[[UIScreen mainScreen] bounds].size.height);
if ([[UIScreen mainScreen] bounds].size.height == 568)
{
//design frames of your controls accordingly add add the controls as subview to
self.view
//this is iphone 5 xib
} else
{
//design frames of your controls accordingly add add the controls as subview to
self.view
// this is iphone 4 xib
}

Obj-C, how do I get the height of a sub view to scale, across all iPhone sizes?

I'm having some trouble catering for the new iPhone 5 screen height, I need to resize my table view already to show an advert.
Up till iOS6 I didn't have a problem, I used the following function, but it doesn't use scale. To be honest I'm surprised it works.
+ (CGRect)setTableBoundsByHeight:(int)lHeight:(UITableView*)tbl {
CGRect tableFrame = tbl.frame;
return CGRectMake(tableFrame.origin.x,
tableFrame.origin.y,
tableFrame.size.width,
lHeight);
}
Here's the code, where I have hard coded the height of my table view at 367, that's minus the height of a navigation controller and a tab bar. 50 is the height of the advert.
if (!productPurchased) {
#ifdef VER_FREE
[[LARSAdController sharedManager]
addAdContainerToView:self.view withParentViewController:self];
[[LARSAdController sharedManager]
setGoogleAdPublisherId:#"number"];
[reportTableView setFrame:[General
setTableBoundsByHeight:(367-50):reportTableView]];
#endif
} else {
[reportTableView setFrame:[General
setTableBoundsByHeight:367:reportTableView]];
}
I've found some code which scales but I'm not sure how to implement this.
CGFloat scale = [UIScreen mainScreen].scale;
result = CGSizeMake(result.width * scale, result.height * scale);
If this code is inside your view controller, just use self.view.bounds.height rather than 367.
By the way: You should really rename
+ (CGRect)setTableBoundsByHeight:(int)lHeight:(UITableView*)tbl
to something like
+ (CGRect)setTableBoundsByHeight:(int)lHeight tableView:(UITableView *)tbl
Ignore the scale, it scales automatically. Just check if iPhone 5 and set different height, but you use iphone5 pixel count/2 as it'll scale it to 2x itself.
Using hard-coded values (a.k.a. "magic numbers") is a wrong habit, you see why now. Always prefer using constants or runtime-computed values. Besides, it makes code easier to read because by using constants you will know what the numbers correspond to, instead of being "magic numbers" coming from nowhere.
So for your problem, compute the height value at runtime using this kind of code below.
// simply use the height of the current viewController's `view`
// which is probably the view of the `navigationController`'s `topViewController`
// and is already at the correct size, namely 367 in iPhone 3.5" and 455 in iPhone 4".
CGFloat screenHeight = self.view.height;
if (!productPurchased)
{
static CGFloat advertHeight = 50;
#ifdef VER_FREE
[[LARSAdController sharedManager]
addAdContainerToView:self.view withParentViewController:self];
[[LARSAdController sharedManager]
setGoogleAdPublisherId:#"number"];
[reportTableView setFrame:[General
setTableBoundsByHeight:(screenHeight-advertHeight):reportTableView]];
#endif
} else {
[reportTableView setFrame:[General
setTableBoundsByHeight:screenHeight:reportTableView]];
}
Note that you don't need to do any substraction yourself, as the UIViewControllers resize their view according to the space available, so that if you have for example a UITabBarController that contains a UINavigationController that itself shows a UIViewController on top of its stack, the height of this last viewController's view will be the height of the screen minus the tabBar, statusBar and navBar heights.
So instead of fetching the [UIScreen mainScreen].applicationFrame for example, and subtract the tabBar (if any) and navBar heights to have your value of 367pt, simply use the height of the viewController's view directly and you should have the right value directly.
Additional note: you should give a prefix to your second argument, thus name your method setTableBoundsByHeight:tableView: instead of setTableBoundsByHeight:: where the second argument does not have any prefix. (See #MrMage answer that suggest this too).
A better naming for your method would even be setHeight:forTableView: for example, to beter fit the Apple naming conventions.

Relativelayout or LinearLayout in ios iphone development?

I want to add a subview in the top of my view, I have to recalculate the origin y value for all of other views and re-position them to leave space for the new added view.
It is very boring, as I know android have relativelayout or linearlayout can help automatically do that.
How to solve this problem easily in ios development?
I've created a library to solve just this problem: CSLinearLayoutView
You use it like this:
// create the linear layout view
CSLinearLayoutView *linearLayoutView = [[[CSLinearLayoutView alloc] initWithFrame:self.view.bounds] autorelease];
linearLayoutView.orientation = CSLinearLayoutViewOrientationVertical;
[self.view addSubview:linearLayoutView];
// create a layout item for the view you want to display and add it to the layout view
CSLinearLayoutItem *item = [CSLinearLayoutItem layoutItemForView:someView];
item.padding = CSLinearLayoutMakePadding(5.0, 10.0, 5.0, 10.0);
item.horizontalAlignment = CSLinearLayoutItemHorizontalAlignmentCenter;
item.fillMode = CSLinearLayoutItemFillModeNormal;
[linearLayoutView addItem:item];
// add more items
I've been trying to do a relative (linear) layout for a while and finally decided to just subclass UIScrollView to get it done.
I started out just replacing layoutSubviews with a simple loop through the subviews that reset the origins while keeping a running Y. But, some unexpected things are added to the scrollview, including UIInlineAutoCorrect views from textfields/views, which means these things were being mangled by the layout. So I added a little bit of logic that uses the tag property of a UIView to determine if I should lay it out:
-(void) layoutSubviews{
CGFloat runningY = 0.0f;
CGFloat widestWidth = 0.0f;
for (UIView *view in self.subviews) {
if (view.tag != 1999) {
continue;
}
view.origin = CGPointMake(view.origin.x, runningY);
runningY += view.height;
if ([view autoresizingMask] == UIViewAutoresizingFlexibleWidth) {
view.width = self.width;
}
if (view.width > widestWidth) {
widestWidth = view.width;
}
}
[self setContentSize:CGSizeMake(widestWidth, runningY)];
}
If you would still like to use unique tags for your views, you should just specify a range of tags that will be included in the layout instead of a single value.
It's not much work to subclass UIView to make sense of methods like -(void)addView:toRightOfView: etc. You could do this as you go, porting only the methods you need. You could then call these in your override of layoutSubviews as Benjamin indicates.
Views can be built using IB or they can be written programmatically; Android scores well here in making layouts readable and you can bring that benefit to iOS views created programmatically. That there are few iOS devices means beyond readability there are not (yet?) many practical benefits to this pattern.
NB. A "XIB" file is an XML file. Open it up in your favourite text editor and take a look.
** EDIT.
Here's a quick example I knocked up. It has not been tested but some thing like this will work in your subclass of UIView (call it UIRelativeView perhaps).
- (void) addSubview:(UIView *) viewOne
toRightOfSubview:(UIView *) viewTwo
{
if (viewTwo == nil ||
[self.subviews contains:viewTwo] == NO)
{
[self addSubview:viewOne];
}
else
{
CGRect frameTwo = viewTwo.frame;
CGPoint originOne = CGPointMake(frameTwo.origin.x + frameTwo.size.width,
frameTwo.origin.y);
CGRect frameOne = CGRectZero;
frameOne.origin = originOne;
frameOne.size = viewOne.frame.size;
[viewOne setFrame:frameOne];
[self addSubview:viewOne];
}
}
- (void) moveSubview:(UIView *) viewOne
toRightOfSubview:(UIView *) viewTwo
{
if (viewTwo == nil ||
[self.subviews contains:viewTwo] == NO)
{
[self addSubview:viewOne];
}
else if ([self.subviews contains:viewOne] == NO)
{
[self addSubview:viewOne toRightOfSubview:viewTwo];
}
else
{
CGRect frameTwo = viewTwo.frame;
CGPoint originOne = CGPointMake(frameTwo.origin.x + frameTwo.size.width,
frameTwo.origin.y);
CGRect frameOne = CGRectZero;
frameOne.origin = originOne;
frameOne.size = viewOne.frame.size;
[viewOne setFrame:frameOne];
}
}
You've got no luck here. iOS doesn't have provisions for positioning the views in different layouts like Android. You need to reposition all the other subviews to make the way for the new view.
There are some view resizing methods like sizeToFit and autoResizingMask but they won't help you in your case here.
iOS is much more focused on pixel accuracy than Android it is, which uses relative layouts as it has to deal with multiple screen sizes. However, in iOS, the Interface Builder is an incredibly good tool included in XCode, which you can use.
Also, if you are just adding subviews in a repetitive manner, you could override the layoutSubviews method and use that to handle to manual labour for you. You mention having to "recalculate the origin y value for all of other views and re-position them to leave space for the new added view" ... You could code that into your layoutSubviews so you don't have to do it yourself each time.
Unfortunately, though, the SDK doesn't have any of this included by default. autoresizingMask's are great but you can't use that for initial layout; it's for automatic really it when rotating only.
As of iOS 9 you can use UIStackView, which works very similarly to LinearLayout: you add views and the stack view arranges them as needed based on your sizing preferences:
Fill will leave three of them their natural size, and make the fourth one take up the most space. It uses Auto Layout's content hugging priority to decide which one to stretch.
Fill Equally will make each subview the same size so they fill all the space available to the stack view.
Fill Proportionally uses the intrinsic content size of each subview to resize them by an equal amount. So view 1 was designed to have twice as much height as views 2, 3 and 4, that ratio will remain when they are resized – all the subviews get proportionally bigger or smaller.
Equal Spacing does not resize the subviews, and instead resizes the spacing between the subviews to fill the space.
Equal Centering is the most complicated, but for many people also the most aesthetically pleasing. It attempts to ensure the centers of each subview are equally spaced.
You can also set spacing between views in the stack view, adding some padding.
WARNING: When adding stack view child views in code you should always use addArrangedSubview() like this:
stackView.addArrangedSubview(someView)
If you try to use plain old addSubview() it won't work correctly, because the stack view won't know to arrange it.
As for removing, you need to be careful to use stackView.removeArrangedSubview(someView) and someView.removeFromSuperview() otherwise the view won't be removed correctly.
You might find my UIStackView tutorial useful.

Help required in converting iPhone App to iPad

I am using the latest Xcode and i created a view based universal app and started building focusing on iPhone and now it is mandatory for me to put it in iPad. I didnt use the Interface builder in the development as more dynamic screen changes were expected from the beginning. In the code i have put all the screens with CGRECTMake(0,0,320,480).
Now when i tried to run the app in a iPad simulator, the app sticks to the top corners of the simulator with width as 320 and height as 480 and the rest of the screen looks white instead of coming up in the middle of the screen with a border and 2x options.
I have made the Main nib file base name (iPad) property in .plist file to my iPhone XIB name. I know this is one major reason why the app sticks to the top, but how to make this generic and make my app look proper in iPad?
Kindly help
If you create your views programatically you have to set everything that has a size twice, once for iPhone/iPod and once for iPad. You can do something like:
if ([Utils isIPad]) {
rect = CGRectMake(0,0,640,1024);
}
else {
rect = CGRectMake(0,0,320,480);
}
[Utils isIPad] would be something like:
+ (BOOL)isIPad {
#ifdef UI_USER_INTERFACE_IDIOM
return (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad);
#else
return NO;
#endif
}
Doing this with nibs is easier and faster, though. You just have to use the correct nib in that case. Something like:
if ([Utils isIPad]) {
login = [[LoginController alloc] initWithNibName:#"LoginController-iPad" bundle:nil];
}
else {
login = [[LoginController alloc] initWithNibName:#"LoginController" bundle:nil];
}
In response to dkk's answer, wouldn't it be more convenient to use the application frame of the main screen? This would return the correct frame size depending on the device without manual checks or hardcoded screen sizes.
[UIScreen mainScreen] applicationFrame]
More info: UIScreen Class Reference, refer to the applicationFrame property