Position UILabel when app is opened in iPad - iphone

I have a universal iPhone/iPad app. On the main menu I have a UIImage and UILabel that show the current weather conditions outside; the UILabel shows the current temperature.
I am using the same XIB for both versions, I made all of the graphics I am using a high resolution so they scale good for the iPad.
On the iPhone version, right under the UIImage the label is centered, which is what I want it to do. When it loads in the iPad, the UIImage gets a big bigger, but the label stays in the same position, to the left of the screen, not centered under the bigger image. I have tried many different things in IB to get it to center, and I cannot get it to.
Would it also be possible to make the text size bigger when loaded on the iPad?
Here are some images to portray what I am talking about:
iPhone version:
http://img855.imageshack.us/i/iphonei.png/
iPad version:
http://img163.imageshack.us/i/ipadh.png/

Not sure about your label issue, but to vary text size for iPad create a function to test if you're on an iPad and then use that to vary your code as required. Here's a function to to do the job.
BOOL isIPad()
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
{
return YES;
}
return NO;
}
And then just write some conditional code. For example:
UIButton *infoCircle;
if (isIPad())
{
infoCircle = [UIButton buttonWithType:UIButtonTypeInfoDark];
}
else
{
infoCircle = [UIButton buttonWithType:UIButtonTypeInfoLight];
}
In your case, you'll want to adjust the label font size with something like:
if (isIPad())
{
[[self mainLabel] setFont: [UIFont systemFontOfSize: 18.0]];
}
else
{
[[self mainLabel] setFont: [UIFont systemFontOfSize: 14.0]];
}
If Interface Builder is giving you grief, you can also use the same approach to reposition the UILabel programmatically. Sometimes this is quicker, especially once your interface has settled down.

Related

XCODE: Adjusting UIImageView Size from NIB for iPhone 5 Devices

I am trying to adjust the size of a background static UIImageView (from Nib file) for iPhone5 users. Unfortunately, the following code does not seem to make any difference on the background view's size.
Does anyone know why? Thanks in advance for any help you can provide.
ViewController.m:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
device = appDelegate.deviceType;
NSLog(#"The device platform is: %#", device);
if ([[device substringToIndex:8] caseInsensitiveCompare: #"iPhone 5"] == NSOrderedSame) {
[background sizeThatFits:CGSizeMake(320, 504)];
}
else {
[background sizeThatFits:CGSizeMake(320, 416)];
}
...
//Note: 'background' is declared in `ViewController.h` as, `IBOutlet` `UIImageView` *background, and is linked to the image view in ViewController_iPhone.xib
A few thoughts:
As demosten and shabzco suggested, I wouldn't use a device name/description to determine coordinates (if nothing else, what about the iPhone 6, etc.);
If you're going to set the frame programmatically, I would suggest setting the background.frame property based upon the view controller's view's bounds rather than hard coding the size of the image view. That way, the background is adjusted to the appropriate size of the view controller's view, not only regardless of device, but also regardless if that view controller is, at a later date, embedded as a child view controller of another container controller, etc. (E.g., what if you put your view in a navigation controller and tab bar controller, your own custom container controller, etc.). Also, don't make assumptions about the size of the status bar or other graphical elements. Let iOS figure all of this out for you with simply:
background.frame = self.view.bounds;
Or better yet, if you've added the background image view to the NIB itself, set the autosizing mask and don't change the frame programmatically at all. If you have autolayout turned off, just set the autosizing properties of your image view like so:
Bottom line, if you can, avoid explicit device name references in your code and avoid hard coded coordinates. To have hardcoded dimensions in your code will just make your app more fragile, susceptible to problems with new devices, new versions of iOS, embedding your view controller in additional container controllers, etc., and limits the reuse opportunities for your code.
Here's a better way to check between iPhone 5 and previous sized devices
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
{
CGSize result = [[UIScreen mainScreen] bounds].size;
if(result.height == 480)
{
[background sizeThatFits:CGSizeMake(320, 416)];
}
if(result.height == 568)
{
[background sizeThatFits:CGSizeMake(320, 504)];
}
}
sizeThatFits does not change size. You should modify background.frame. Something like:
background.frame = CGRectMake(background.frame.origin.x, background.frame.origin.y, 320, 416);
and
background.frame = CGRectMake(background.frame.origin.x, background.frame.origin.y, 320, 504);
Also make sure your UIImageView does not have flexible width or height in Size inspector tab while editing your Nib file.

UIButton custom retina image stretched in iPad Retina Display

I have one issue with iPad retina image. When i was executing my add in normal ipad it looks great.
But when I am executing this app in iPad Retina then UIButton custom images is stretched upwards.
Also I added images for "#2x" icon images for retina mode.
Using this code:
UIButton *btnEye=[[UIButton alloc] initWithFrame:CGRectMake(10, 5.5, 35, 35)];
[btnEye setImage:eyeImage forState:UIControlStateNormal];
[reportToolbar addSubview:btnEye];
In Normal Mode :
In Reitna Mode:
Are the retina images really having double resolution than normal or it has the same resolution as the normal one?
simply , you should replace the "#2x" images with the normal ones , it seems, the images' sizes are reversed .
This code would not win the beauty contest but you could give it a try!
Add a function to your class to recognise if you have a retina device
- (BOOL)isRetina {
return [self respondsToSelector:#selector(displayLinkWithTarget:selector:)] && (self.scale == 2.0);
}
And when you set the eyeImage do this
UIImageView *eyeImage = nil;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad && [self isRetina]) {
eyeImage = [UIImageView imageNamed:#"eye#2x.png"];
} else {
eyeImage = [UIImageView imageNamed:#"eye.png"];
}
This way you force your device to use the retina image if it has one :-).

Fade out Launch Image on 4 Inch iPhone screen

On launch, I am fading from my launch image to the application's interface. To achieve this, I am adding a UIImageView with "Default.png" and animating its alpha just before makeKeyAndVisible.
Should Default.png always return the device-specific (or resolution-specific) version of the launch image? Or should I be checking the screen's bounds and scale to pick the right one for the retina vs non-retina and 3.5 vs 4 inch screens?
I expected Default.png to behave much like other image resources - use the #2x version when supported (and the -568h version on the iPhone 5). But my experimentation in the simulator leads me to believe otherwise. Running the 4 inch simulator, the 3.5 inch image is used. This results in a splash image that does not extend to the bottom of the screen. The screenshot below shows the transition mid-animation.
Unfortunately I don't have each device so was unable to confirm if this is just a quirk of the simulator.
In short, I want to be sure that the retina image is used on retina devices, and the 4 inch image is used on 4 inch devices.
This is my code
- (BOOL) application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[self.window makeKeyAndVisible];
[self _startLaunchAnimation];
return YES;
}
- (void)_launchAnimation {
CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
UIImageView *launchImageView = (UIImageView*)[self.window viewWithTag:1000];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionNone
forView:self.window
cache:YES];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:#selector(startupAnimationDone:finished:context:)];
[launchImageView setAlpha:0.0];
[launchImageView setFrame:CGRectMake(-60.0f, 0.0f, 320.0f, screenHeight)];
[UIView commitAnimations];
}
- (void)_startLaunchAnimation {
CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;
NSString *imageName = nil;
if (screenHeight == 568.0f) {
imageName = #"Default-568h.png";
} else {
imageName = #"Default.png";
}
UIImage *image = [UIImage imageNamed:imageName];
UIImageView *launchImageView = [[UIImageView alloc] initWithImage:image];
[launchImageView setTag:1000];
[self.window addSubview:launchImageView];
[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:#selector(_launchAnimation)
userInfo:nil
repeats:NO];
}
For the record, this is my version of #agassi_yzh's solution:
//fade from the launch image to the interface
CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height;
NSString *imageFile = (screenHeight == 568.0f) ? #"Default-568h.png" : #"Default.png";
UIImageView *splash = [[UIImageView alloc] initWithImage:[UIImage imageNamed:imageFile]];
[self.window.rootViewController.view addSubview:splash];
[UIView animateWithDuration:0.5
animations:^{
splash.alpha = 0;
}
completion:^(BOOL finished) {
[splash removeFromSuperview];
}
];
//display the main window
[self.window makeKeyAndVisible];
The answer is you will have to explicitly load the device specific version of the image. This is custom animation and you cannot rely on Apple's Default whatever loading behavior to achieve what you want.
First make sure that you you are configured properly and the correct default load image is displayed on the devices (dont trust the simulator too much (aka I never even use the simulator its so buggy))
And then as previous commenters suggested load a view with your images.
Remember that the default image is going to be loaded and shown by the cocoa framework. All you can do is show a view afterward, if you try and do some of the admittedly clever hacks with the on load that are on the web you will find that they will always break in some way.
If you need a full screen image animated or not on iPhone 5 you need to load that image explicitly for the device thats all there is to it.
Yes, you provide Default.png and Default#2x.png, you even have to supply Default-568h#2x.png for the iPhone 5 4" screen.
You app will use standard, retina or big retina according to device but note that Apple discourage using the Default launch image as any intro animation sequence.
The trick you could use is to add an image view as the first screen of the app when it's launched and immediately fade it out, this will give the user the impression that the launch image is fading out even though the launch image is gone, and it's your image view taking over.
Look at the Launch image section of the Apple Custom Icon and Image Creation Guidelines:
Supply a launch image to improve user experience.
Avoid using your launch image as an opportunity to provide:
• An “app entry experience,” such as a splash screen
• An About window
• Branding elements, unless they are a static part of your app’s first
screen Because users are likely to switch among apps frequently, you
should make every effort to cut launch time to a minimum, and you
should design a launch image that downplays the experience rather than
drawing attention to it.

how to set the postion for UILabel in Different UIOrientation

I have a view and I am creating a UILabel programatically and calling it my parameter passing as I need many UILabel text with Different Position frame, so I am calling it by parameter passing.
Using the code below, when I rotate to landscape mode the portrait view Label still appears. How do I overcome this? I need to be done in the below code. I want the position of the Label frame to be changed from portrait view to landscape view.
NOTE:I need to Create many Label,s around 15 to 20, so I am using parameter passing, so that I don't need to write as many methods for creating each label.
-(UILabel*)createLabel:(CGRect)frame :(NSString*)labelTitle
{
UILabel *myLabel = [[UILabel alloc] initWithFrame:frame];
[UIFont fontWithName:#"Arial" size:13];
myLabel.text = labelTitle;
}
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
if(interfaceOrientation == UIInterfaceOrientationPortrait || interfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
{
[self.view addSubview:[self createLabel:CGRectMake(450,140,60,20):#"Ratings:"]];
[self.view addSubview:[self createLabel:CGRectMake(450,170,60,20):#"Reviews:"]];
}
else
{
[self.view addSubview:[self createLabel:CGRectMake(650,140,60,20):#"Ratings:"]];
[self.view addSubview:[self createLabel:CGRectMake(650,170,60,20):#"Reviews:"]];
}
return YES;
}
Don't create them in shouldAutorotateToInterfaceOrientation, because it will get called everytime the orientation changes, thus creating more labels.
Instead create them once in - (void) loadView, and give them the correct autoResizingMask properties, e.g:
myLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth ;
This will cause the desired behaviour when the orientation changes: the labels will automatically resize and the whole turning animation will be smooth.
PS: Mind that the way you were creating Labels is causing a memory leak, use the release method to prevent this.
The label for portrait orientation still appears because each time the device is rotated, you are adding a new label without removing the old one.
I think it is not a good idea to create new labels while you can just change the frame of the existing ones. To do this, you should add two properties (say reviewLabel and ratingLabel) to your class and assign your labels to these when they are first created. Then on your shouldAutorotate function, you can access these labels and change their frame.

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