Changing resources programmatically in Objective-C iOS 5 for Retina Display - xcode

My app have a background image that fills the screen. I'd like to display the correct .png file depending on if we're on a Retina Display device or not. I already have added all the .png files for both iPhone and iOS with the correct sizes. Is it possible ? If not, how should I handle it properly ?
I have XCode 4.3.2 with iOS 5.1 as the deployment target.

If you name your graphics properly (e.g. add "#2x" to the suffix of the png files), iOS is smart enough to use your Retina display graphics on the appropriate devices & displays. Especially if you are using UIImageViews or controls or whatever, within your user interfaces designed within XIB files.
If you're doing programmatic images (i.e. where you define an outlet and then grab an image via something like "[UIImage imageNamed:], iOS is still smart enough to pick up the high rez images for you. Again, provided you named your graphics properly.
There are other questions here on StackOverflow that might help you out, such as:
How to support both iPad and iPhone retina graphics in universal apps
How to activate #2x high res graphics for retina display?

This probably would work. First it checks if the screen has a retina display, and if it does, sets the background image to the retina image. If it does not have a retina display, the background image is the regular image. You can put this in viewWillAppear or viewDidLoad.
if ([[UIScreen mainScreen] respondsToSelector:#selector(displayLinkWithTarget:selector:)] &&
([UIScreen mainScreen].scale == 2.0)) {
// Retina display
UIImage *backgroundImage = [UIImage imageNamed:#"retinaImage.png"];
} else {
// Non-Retina display
UIImage *backgroundImage = [UIImage imageNamed:#"nonRetinaImage.png"];
}
Hope this helps!

Related

How to prevent Storyboard from resizing (stretching) a UIImage centered on a UIView?

I have a Universal iOS app and am trying to move from old-style launch images to a simple centered image on a storyboard Launch screen, so I have a single storyboard for all devices. My image (640x1136, iPhone 5s size) needs to not be stretched when the app is run on devices with larger sizes than the image -- in other words, the background color of the UIView should appear surrounding the image on larger devices. For debugging purposes I changed the view background color to a gaudy Lime.
I defined 2 constraints on the UIImageView as directed in the SO post here according to the highest-upvoted answer (Suragch's) and in fact had to also follow the accepted answer's recommendation to add the additional UIView into which my UIImageView would be contained.
The "content mode" of the UIImageView is Center so seems there should be no stretching.
In the pic notice Xcode's Size Inspector settings for the UIImageView. The UIView has iPhone 7-sized dims (750x1334) and so because that iPhone is taller than my image the UIImageView is positioned so that its X is 55, Y is 99. The width and height are same as the image itself (640x1136).
When I run in Simulator an iPhone 7 seems it should look like exactly as what Xcode's Interface Builder shows (Lime color appearing all around the image, but instead, for any device larger than an iPhone 5s or SE it looks like the pic I've attached (an iPad Air, FYI). You can tell the image must be stretched quite a bit vertically because the image is only 1136 tall.
I've attached screenshots for the iPhone 7 (simulator) iPad Air and iPad Pro. Notice the horizontal strips of lime color appear on the right and left edges of the iPad Air. And notice that when it comes to the iPad Pro the lime background color begins to be shown above the image. It's as if on the smaller devices the system is stretching the UIImageView, but as device screen size increases this eventually stops, until for the largest (the Pro) you can actually see the background all around. It seems that for all device sizes listed in the Apple docs that are taller than iPhone 5s or SE, there should be no stretching/distortion. This is what I'm trying to accomplish.
Interface Builder size settings
iPhone 7 (simulator) screenshot
iPad Air (device) screenshot
iPad Pro (device) screenshot
I was able to get this to work finally, by completely eliminating the constraints and only using the autoresizing settings found when you choose the Size Inspector. The UIImageView now retains its specified size and is not stretched.
Try adding a width/height constraint to your ImageView:
This is done by first selecting your ImageView and then selecting this |-☐-| icon (located at the bottom right of the Storyboard window, next to the option where you can change the type of device)
Okay, I think I've figured out the problem. Your image is sized too large. You say you want it to be the size of an iPhone 5, and it's display size is 1136x640 pixels. This is not the same as the width/height in Xcode. To get this, change the device to iPhone 5 (or similar) and get the size. For instance, the size of the View for an iPhone 8 is 667x375. Then your image won't be cut off.

Force a retina iPad to use non-retina images

I'm creating an app using OpenGL...
I have a retina iPad, and I'm using a texture that stores #2x images. When my app starts up, the OpenGL framebuffer is created and querying the size of it comes back as 1536x2048 - so far so good.
I also have a texture for non-retina iPad display (768x1024), but I do not have a non-retina iPad. I'd like to force my retina iPad to use the non-retina graphics (i.e, for it to use scale == 1.0). So I'd like it to create a 768x1024 OpenGL framebuffer. The problem is that it always creates a 1536x2048 frame buffer, and scale is always 2.0.
Is there a way of forcing it to use a scale of 1.0, and creating a smaller framebuffer? The base iOS version for the app is 8.0, but since iOS8.0 still works on the iPad2, I'd like to test that resolution as well.
I've tried using UILaunchImages, but that doesn't seem to work? In the past, when an app was written for a non-retina screen, a retina device used to scale the lower resolution to fit the higher-resolution screen, and that's what I want - at least so I can test....
Is UILaunchImages the right way to go to try and get iOS to think that only low-res graphics are available?
IIRC, simply by having an #2x resource (splash, icon, etc..) used to signal iOS that you are running an app with support for Retina. I think since then Apple has added a NSHighResolutionCapable key that you can try to set false in the plist. So try removing all #2x resources from your build and setting that key to false.
Another approach is to change your glViewPort and/or the Projection matrix to scale your logical resolution to 1024x768. I have the opposite problem in that I need to scale non-retina images up to the retina backing scale. I use a Scaling matrix in my stack to fix this.
Ask me how I mix and match retina and non-retina images!

Pinch to zoom gesture working perfectly on ipad2 but not on retina iPad?

The title of the question speaks itself. For more assistance I would like to tell that my app has been developed using the Apple Photo Scroller(A modification of Apple's PhotoScroller sample code to load the UIPageViewController inside a UIViewController subclass
), with multiple image galleries. The problem is the pinch-to-zoom functions perfectly on ipad2 but not on retina iPads. My images are of size 2048x1536.
Can anybody tell me why the zoom is not working on retina iPads?
I would start by checking that the contentScaleFactor is set to 1.
From PhotoScroller's TilingView.m file:
// to handle the interaction between CATiledLayer and high resolution screens, we need to
// always keep the tiling view's contentScaleFactor at 1.0. UIKit will try to set it back
// to 2.0 on retina displays, which is the right call in most cases, but since we're backed
// by a CATiledLayer it will actually cause us to load the wrong sized tiles.
//
- (void)setContentScaleFactor:(CGFloat)contentScaleFactor
{
[super setContentScaleFactor:1.f];
}
See these related questions and answers here and here for more info on contentScaleFactor.

how to set image for ipad application that support retina display

i need to update my application so it can support retina display in New iPad, but i still have some doubt about it. Is it right that we have to create a new image that support the resolution for retina display and still keep the last image for the application without retina display support? If yes, so our app will have a big size, right? Is there any way to make it just one? Maybe just use the high resolution image, but resize them for the regular application (the application that did not support retina display). Can somebody help me?
You have to create two images. one for old resolution and one for retina display.
If i remember, you have only to add #x2 on retina images:
mypicture.jpg (old display)
mypicture#x2.jpg (retina display)
I hope, this way is similar to the iphone.
For web you can still use the #2x naming convention.
Declare the background image and set the size.
In the retina display media query call the high-res image.
figure{background-image:url(../img/imageName.png);background-size:57px 57px;}
#media only screen and (-webkit-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min--moz-device-pixel-ratio: 1.5),
only screen and (min-device-pixel-ratio: 1.5) {
figure{background-image:url(../img/imageName#2x.png);}
}
There are server side solutions too, here's one: Link

set ios screen resolution in xcode4 storyboard

Am working on an ipod/iphone application that primarily captures a photo. Am designing the flow in xcode4 IB storyboard.
However, as you can see from the image it is taking the default resolution as 320x480 which causing the preview on ipod retina display to show up in a corner than full screen. How can I make the IB get device resolution and adjust the ratio accordingly?
I tried looking at project settings, build settings, info.plist however couldn't find an answer yet.
Thx
Those dimensions are in points, not pixels. They are correct. On retina displays, 320 points are equal to 640 pixels. If your application is only showing up in a quarter of the screen, it's likely the problem is in your code, not in how you have set things up in Interface Builder.

Resources