Resize image in UITableViewCell to not be total height - iphone

Current I am trying to show a simple table in my iPhone application where I use UITableViewCell's with the style UITableViewCellStyleValue1 (image to the left, detail-label right-alligned). The cells all have the default height (50.0f). Before I add an image to the cell, I resize the image to be 40x40, so that it is not the total height of the cell (I think that looks ugly).
I do this with this code:
cell.imageView.image = [UIImage imageNamed:#"icon.png"];
cell.imageView.image = [RootViewController imageWithImage:cell.imageView.image scaledToSize:CGSizeMake(40, 40)];
This is all very nice and works flawlessly. But I want to accomplish this also on the iPhone 4 (with the higher resolution screen). The problem is, that everything is scaled without problems on the iPhone 4 but the images appear very pixelated.
The reason for this is ofcourse that everything on the screen is blown up to scale to the new resolution, also the images, so the images should probably be something like 80x80. But when I resize them to 80x80 (originals are 120x120) they appear way to big, because of the scaling thing.
Is there a way to actually make my images not the complete height of a tablecell, but I want them in the higher resolution on the iPhone 4. Should I create a complete new View for this?
Oops, after the first reply I realised that my own written function was missing:
+ (UIImage*)imageWithImage:(UIImage*)image scaledToSize:(CGSize)newSize
{
UIGraphicsBeginImageContextWithOptions(newSize, NO, [[UIScreen mainScreen] scale]);
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
As you can see, after the first reply, I tried to get this to work with the method UIGraphicsBeginImageContextWithOptions but somehow this results in an empty image.

I assume you wrote "imageWithImage:scaledToSize:", right?
I further assume you use "UIGraphicsBeginImageContext(yourSize)" within this call. Replace that with "UIGraphicsBeginImageContextWithOptions(yourSize, NO, 2.0)" in case your platform is iPhone 4.
The "2.0" defines the scale factor for points (you define the size in points not in pixels). On pre-retina-display a point is 1x1 pixel. On retina display a point is 2x2 pixels.
Edit:
Make sure you have a high-res version of "icon.png" in your resources called "icon#2x.png". This is automatically loaded in case it is a retina display.

Related

switch background image iphone5 - iphone4

In my FirstViewController I have write this code for switch background if device is iPhone4 or iPhone5:
Filename:
bg-for5-568#2x.png
bg-for4#2x.png
bg-for4.png
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *backgroundImage = [[UIImage alloc] init];
if([[UIScreen mainScreen]bounds].size.height == 568)
{
backgroundImage = [UIImage imageNamed:#"bg-for5-568h"];
}
else
{
backgroundImage = [UIImage imageNamed:#"bg-for4"];
}
self.view.backgroundColor = [[[UIColor alloc] initWithPatternImage:backgroundImage] autorelease];
[backgroundImage release];
}
When i lanch the app on my simulator, the background for iphone5 show double size, out of the view.
/* RESOLVED THANK YOU */
I am not sure if this is the solution for this problem as I am missing some infos, but:
At first: Strip the .png from your imageNamed: method. Since iOS4, you shouldn't do this anymore. The next thing is: What are the Names of your image? Note that an iPhone5 has a retina display, and your image should be named bg-for5-568h#2x.png but referred in the sourcecode as bg-for5-568h.
Besides that: In almost every case where your image isn't a photograph, what you are doing is a bad idea. And even if it is a photograph, simply use the bigger image for the iPhone 4 and 4S as well. It's not that much bigger, so the memory footprint isn't a problem here! Have a look on UIImageView's contentMode property. You can use this to adjust the position of the larger image. You also might want to check UIImageViews clipSubviews property to clip the image if it isn't fullscreen.
Trust me, in my company we had a loot of hooks for stuff like ~ipad, ~iphone, ~2x and even stretchable images. And all these hooks worked fine till the date, apple announced something similar or simply a new device. So I decided to not do these kind of hooks anymore. They seem to be very helpful in the first place, but the trouble you get when there is something new on the market isn't worth it!
You should append #2x suffix to all of your retina images.
In your case your image should be stored as "bg-for5-568h#2x.png".
Hope it will resolve the issue.
I would not advise doing this, what if Apple change their screensize again and you have to go back and rewrite all your code?
A simple fix is to use:
self.view.backgroundColor = [UIColor colorWithPatternImage:/* your image*/];
This could give you some issues with stretching or tiling.
I prefer using
UIImage* imageName = [[UIImage imageNamed:/*image name*/]resizableImageWithCapInsets:UIEdgeInsetsMake(top,left,bottom,right)];
In iOS 6 you can improve this further by defining if you want the image to stretch or tile. This allows you to create a border which won't change and then the centre of your image by default being tiled and filling the space of your imageview

Why UIImage View showing wrong Size of Image

I have image files of dimension 1900x1200. In my code I try to load it as
UIImage *image = [UIImage imageNamed:imageName];
When I try to run this code in iPhone Simulator (Retina Display) my images look out of proportion. I tried to print
image.size.width and image.size.height
and the value I get is 950x600.
What I am doing wrong. Please help me out.
The answer is actually simple: the UIImageView (and the underlying UIImage) are using scale factor 2.0. That is your 1900x1200 pixels image correspond to 950x600 points image with scale factor 2 on retina display. You can double check the UIImage's scale property.

How do I use CGRectMake to size the background

Ok So I have this code, which allows me to put a background image in:
I would love to know how to size this, so on the iPhone 4 I can get a 320x480 size but make it nice with an image of 570.855.
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background_stream-570x855.jpg"]];
I have tried this:
UIImageView *image = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:#"background_stream-570x855.jpg"]];
[self.view sendSubviewToBack:streamBG];
image.frame = CGRectMake(0, 0, 320, 480);
Which works, however the problem is it's behind the view, so I can't see it. I could make the view clear, but it has objects on it that need to be displayed.
Any help would be most apretiated
There are multiple options to put Views at desired location.
[self.view sendSubviewToBack:streamBG]; //Sends subview to last position i.e. at the last
[self.view bringSubviewToFront:streamBG] //Brings subview to first position i.e. at the first.
[self.view insertSubview:streamBG atIndex:yourDesiredIndex];//Put at desired index.
This is not answer to your question, though it may help you to set your imageview to desired location.
Hope it helps.
To answer part of your question about sizing. You need to use 2 different images for your app if you want the full resolution of the retina display (iPhone4) You should provide a 320x480 image (i.e. myImage.png) for older iPhones and one at twice the resolution, 640x960, for the iPhone 4. Use the exact same name for the high res version but add an "#2x" to the end (i.e. myImage#2x.png). In your code all you ever have to call is the base name (i.e. myImage.png) the app will choose the correct image based on the hardware its running on. That will get you the best experience on your app.
On the other part about the background view visibility, you could make the background color clear ([UIColor clearColor]) on the view that is blocking it. That would leave the content visible in that view but the view its self would be clear. Alternatively you could just insert the background at a specific index as #Jennis has suggested instead of forcing it to the back.

Stretchable image stretching part wider than 1px

I would like to create a UIButton which uses a stretchable image as Background image such as that I can easily resize the button for different labels etc.
So I created the following code which works fine:
UIImage *bgImage = [[UIImage imageNamed:#"Button-Template.png"]stretchableImageWithLeftCapWidth:2 topCapHeight:2];
UIButton *loginButton = [UIButton buttonWithType:UIButtonTypeCustom];
loginButton.frame = CGRectMake(180, 280, 112, 40);
[loginButton setBackgroundImage:bgImage forState:UIControlStateNormal];
// some more stuff
Now here is the catch: The iPhone SDK assumes that the strechable part of the image is exactly one pixel in width, which is not the case in my image as I want to create a pattern, which requires a repetition every two pixels (so 2 Pixels are one pattern unit). I have found no information in the docs whether it is possible to alter the value of the strechable part width (in my case 2 instead of 1), does anybody know how to do this or how I could achieve my goal with a workaround? Writing the stretching part on my own seems a little far fetched right now (though I might have to get back to this).
Thanks!
From iOS 5.0 on you could use resizableImageWithCapInsets:
Check UIImage Class Reference
But this method only works on iOS >= 5.0 devices, so that can be a
turn down for now.
There is no API for using 2 pixels as the stretch width. You'll have to implement this behaviour yourself in a custom view, or use an image with a specific width.

How to determine image coordinates for a large cropped image within a UIImageView?

With regards to the iPhone SDK:
I have a 512 x 512 pixel .png image, and I want to display it within a 200 x 200 pixel UIImageView WITH cropping (at native resolution, without zooming, fitting, or rotation). Is there a way to determine the image's coordinates that are visible inside the UIImageView?
For example, if the image in the exact center of the UIImageView, then I want to know what the coordinates of the image are at UIImageView's (0,0) and (200,200) points, which will be (156,156) and (356,356), respectively for the image being displayed.
I plan on implementing "pan" and "zoom" functions at some point, but I want to know how to address this issue first. The UIImageView class reference did not seem helpful... I was hoping to avoid using a UIView, but if that is necessary I will go that route.
Thanks!
You're right about what you've seen from the UIImageView reference - there is no easy way to do that using UIImageView alone. You would need to take into account things like the contentMode of the UIImageView or limit yourself to only calculating the position for a single UIViewContentMode.
However, when you eventually get to implementing pan and zoom, you'll be using a UIScrollView with a UIImageView as a subview of that UIScrollView. At that point, it would be most sane to size your UIImageView initially to the size of whatever image you're display (could be dynamic). You can then determine where the image is by determining where the image view is, which is something you can accomplish much more simply and with just a bit of math.
Thanks for your help. Working out the pan/zoom features became trivial after implementing the UIScrollView. Implementing the UIScrollView let me determine the coordinates I needed with the myScrollView.bounds.origin.x and myScrollView.bounds.origin.y values... zooming still requires calculation - as you stated above, but I am on the right track now.
here is the code I used to make the UIScrollView (based on multiple sources available on the net and this site - Apple's ScrollViewSuite was particularly helpful. Here is the code I used in the (void)viewDidLoad section of my program, hopefully others can find it useful:
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[imageArray objectAtIndex:0]]; //imageArray is an array/stack of images...
[self setMyImage:tempImageView]; //myImage is of type UIImageView
[myImage setTag:100]; //set this to an 'arbitrary' value so that when I update the scrollview I can remove the current image...
[tempImageView release];
myScrollView.contentSize = CGSizeMake(myImage.frame.size.width, myImage.frame.size.height);
myScrollView.maximumZoomScale = 10.0;
myScrollView.minimumZoomScale = 0.15;
myScrollView.clipsToBounds = YES;
myScrollView.delegate = self;
[myScrollView addSubview:myImage];