Image View Deprecated Method - iphone

The content stretch property is deprecated in iOS 6.0, and I can not find an alternative that seems to work right.
Here is the code that works but deprecated in iOS 6.0:
UIImageView *sectionsSeparator = [[UIImageView alloc] initWithFrame:CGRectMake(x, 0, separatorWidth, totalHeight)];
sectionsSeparator.image = [self imageForSectionsSeparator];
sectionsSeparator.contentStretch = CGRectMake(0, 0.25f, 1, 0.5f);
[self addSubview:sectionsSeparator];
I tried the code below, but the images do not line up correctly:
UIImageView* sectionsSeparator = [[UIImageView alloc] initWithFrame:CGRectMake(x, 0, separatorWidth, totalHeight)];
[sectionsSeparator setImage:[[self imageForSectionsSeparator] resizableImageWithCapInsets:UIEdgeInsetsMake(0.0f, 0.25f, 1.0f, 0.5f)]];
[overlayView addSubview:sectionsSeparator];
Maybe i'm missing something, any suggestions?

Being deprecated doesn't meant it stopped working, it just means that you should prefer an alternative but the old way is still valid.
Anyways, if you want to avoid the deprecated thing, you can create an stretchable image as it is specified in the documentation:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIView_Class/DeprecationAppendix/AppendixADeprecatedAPI.html
Edit:
The cap inset method is the opposite of the content stretch one (it works backwards). On the content stretch you cover with a rect what you want to be stretched, here is an example:
http://j0ris.tumblr.com/post/7345178587/uiview-contentstretch
However on the resizableImageWithCapInsets you cover what you DON'T want stretched.
During scaling or resizing of the image, areas covered by a cap are
not scaled or resized. Instead, the pixel area not covered by the cap
in each direction is tiled, left-to-right and top-to-bottom, to resize
the image.
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIImage_Class/Reference/Reference.html#//apple_ref/occ/instm/UIImage/resizableImageWithCapInsets:
So you the insets should be made differently.

Related

How to resize UIImage created with resizableImageWithCapInsets when used for an UIImageView / UIView

I'm writing code to use a custom image as the background for a UIView.
The app runs in portrait only. Prior to the 4" retina screen, I used fixed size, hand-drawn png as the background image (card.png below). I had code like this:
UIView* frontView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height)];
frontView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
UIImage* cardImage = [UIImage imageNamed:#"card.png"];
UIImageView* im = [[UIImageView alloc] initWithImage:cardImage];
im.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
[frontView addSubview:im];
// frontView has a bunch of stuff added...
As you'd expect, when I run this on an iPhone 5, everything can be dynamically sized and positioned, except for the hand drawn png, card.png. So that background image isn't using the full height that is available...
So what (I think) I want to do, is something like this...
UIImage* cardImage = [[UIImage imageNamed:#"card_resizable.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(72, 0, 60, 0)];
I've redrawn card.png as card_resizable.png - it's 140 pixels in height, there's an 8 pixel chunk in the middle, which I want to tile, so the top inset is 72 pixels tall and the bottom inset is 60 pixels tall.
What's the next step?
Should I create the UIImageView with the dynamic size of frontView?
How do I make the resizable image, resize?
The few things that I've tried... none of them have resulted in tiling the resizable image.
Cheers,
Gavin
Update:
I was incorrectly setting the pixel values for UIEdgeInsetsMake(72, 0, 60, 0)
These values are based on the #2x image. When changed to UIEdgeInsetsMake(36, 0, 30, 0) - I get the correct, vertical resizing.
As Mike pointed out, I needed to set the size of the UIImageView to the parent, and correctly set it's autoresizingMask:
im.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
I know have the UIImageView sized dynamically sized, correctly, to fill its parent view - frontView (I've given it a green background to check visually on both 3.5" screen and 4" screen.
The resizable image, cardImage, is also resizing, correctly, in the vertical plane.
Once you've passed the stretchable image to a UIImageView you just resize that image view to whatever height you need.
In your case, you probably want to make the image view fill its parent by doing this:
im.frame = frontView.bounds;
im.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[frontView addSubview:im];
We make im fill the frontView and tell it to automatically increase its width/height when its parent (frontView) changes size. This should do what you want.
Can you try with stretchableImage
UIImage *image = [UIImage imageNamed:#"card_resizable.png"];
UIImage* cardImage = [image stretchableImageWithLeftCapWidth:0.0f
topCapHeight:70.0f];
Take a look at UIView contentMode property. it should give you some sense about how the UIImageView render the image inside, whenever it change it's size.

Image not resizing using CapInsets correctly

I have created a singup button as follows:
signupButton = [[UIButton alloc] initWithFrame:CGRectMake(10,(facebookLoginButton.bounds.size.height + 40),300,50)];
signupButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
UIImage *signupButtonImage = [[UIImage imageNamed:#"Signup"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 10, 0, 10)];
[signupButton setBackgroundImage:signupButtonImage forState:UIControlStateNormal];
The frame for the button is 300x50 per the above. I have created an image (for Retina devices) as 22(w)x100(h)px.
The image is 22 pixels which includes 10px rounded corners and 2px which are for the repeatable middle section.
I have tried to implement the stretch per the above code with insets as 0,10,0,10 but this does not stretch as expected.
Can someone explain what the insets should be? Also how to work these out, I cannot find any useful information on how to actually calculate what the insets should be? I have read the Apple documentation on this, but I do not understand how to work these out.
Your image has size 22x100 but it is a retina image.
That means the point size is 11x50.
The insets should be UIEdgeInsetsMake(5.0f, 5.0f, 5.0f, 5.0f)
Create stretchable Image using following code and assign it to respective UIImageView
UIImage *bgImage = [[UIImage imageNamed:#"Signup"] stretchableImageWithLeftCapWidth:10 topCapHeight:10];
you need to calculate TopCap and LeftCap of your 9 patch image properly.
Good luck.

iOS - trying to rotate a text label and the label disappears

I'm trying to rotate a label on my view 90 degrees. I've tried the two following ways to do it and the label just disappears from the screen. I triple checked that the properties are properly attached. Any thoughts?
attempt one:
// rotating labels 90 degrees
self.labelCloseScroll.transform = CGAffineTransformMakeRotation (3.14/2);
attempt two:
CGAffineTransform rotate = CGAffineTransformMakeRotation(3.14/2);
rotate = CGAffineTransformScale(rotate, 1, 1);
[self.labelCloseScroll setTransform:rotate];
I am not 100% sure if it works or not but why are you not using M_PI_2. It's just simple thought that you are assuming Value of Pi to be 3.14 but the exact value is 3.14159...
I did it like this and it worked fine :
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 50, 70)];
lbl.text = #"New";
lbl.backgroundColor = [UIColor clearColor];
lbl.textColor = [UIColor whiteColor];
lbl.highlightedTextColor = [UIColor blackColor];
lbl.font = [UIFont systemFontOfSize:12];
lbl.transform = CGAffineTransformMakeRotation(M_PI_2);
[self.view addSubview:lbl];
You can also check Answers from these Questions :
How to Render a rotated UIlabel
Rotating UILabel at its center
Hope it will be helpful for you.
It may simply be that the view's bounds have become too small for the text. When the text can't be fully displayed in label view in iOS, it simply disappears, rather than remaining on show. Perhaps it's a deliberate Apple policy to prevent apps shipping with clipped text and forcing the dev to fix ;)
It sounds very much as though this is what is happening. You have said the text gets smaller as you rotate it, which indicates you have the shrink text to fit property set on the label view. This will shrink the text as the constraining view reduces in size. But the text will only shrink so much before it disappears.
If the label view itself would seem to be big enough, also be sure to check the bounds of each parent view the label is contained in, up through the view hierarchy.

Stretchable Images

In reference to: iPhone stretchableImageWithLeftCapWidth only makes "D"s
I have an image of a button of size 13x30. I want to stretch the image to fill the button which will be of size 45x30.
Here is the code I am using:
UIImage *shareImage = [[UIImage imageNamed:#"btn_red"] stretchableImageWithLeftCapWidth:16.0f topCapHeight:0.0];
UIButton *shareButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 46.0f, 30.0f)];
etc....
The image I get is quite off. I am getting the image in its real size, with some sort of a lighter shadow behind it as shown in the image .
Why is this happening? I don't understand at all. I have the stretchable logic correct and I've followed what everyone is saying in tutorials/posts.
If I get some assistance I would greatly appreciate it.
I think your left cap width is wrong? If your first image is only 13 pixels wide, how can the left cap be 16?
The left cap is the width on the original image that stays unstretched
To follow up on Paul's answer,
You want to make sure that you leave some space for stretching, so zoom in using Photoshop or something similar and decide what left pixels are absolutely required.
See this: http://idevrecipes.com/2010/12/08/stretchable-images-and-buttons/
LeftCapWidth should be 6.5;
UIImage *shareImage = [[UIImage imageNamed:#"btn_red"] stretchableImageWithLeftCapWidth:6.5 topCapHeight:0.0];
UIButton *shareButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 46.0f, 30.0f)];

How do you fix missing "blocks" of data when taking screenshots on an iOS device?

I have a problem that I can't seem to fix. I am trying to take a screen-shot of a UIScrollView (including off-screen content) but when the view is long the renderInContext doesn't get all the contents of the scroll view. The produced image dimensions are correct but the rendered data appears to be missing chunks of the display leaving white space where those chunks should be. The missing blocks are from the content in a UIWebView, which I believe is set to "scaleToFit". It doesn't happen everytime, it appears to only happen when the UIWebView's height if fairly large. Which makes me think is has to do with the scaling of the UIWebView.
If I adjust the coreLayer.bounds CGRECT below I get different results, sometimes the missing blocks are at the bottom and sometimes they are in the middle of the image.
I started with the code from the accepted answer of this question and when I noticed the cutoff issue, I modified it to the following:
UIGraphicsBeginImageContext(scrollView.contentSize);
{
CGPoint savedContentOffset = scrollView.contentOffset;
CGRect savedFrame = scrollView.frame;
//hide the scroll bars
[scrollView setShowsHorizontalScrollIndicator:NO];
[scrollView setShowsVerticalScrollIndicator:NO];
scrollView.contentOffset = CGPointZero;
scrollView.frame = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);
//adjust layer for cut-off
CALayer *coreLayer = scrollView.layer;
coreLayer.bounds = CGRectMake(0, 0, scrollView.contentSize.width, scrollView.contentSize.height);
[coreLayer renderInContext: UIGraphicsGetCurrentContext()];
//[scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
image = UIGraphicsGetImageFromCurrentImageContext();
scrollView.contentOffset = savedContentOffset;
scrollView.frame = savedFrame;
//reset the scroll bars to default
[scrollView setShowsHorizontalScrollIndicator:YES];
[scrollView setShowsVerticalScrollIndicator:YES];
}
UIGraphicsEndImageContext();
The cut-off adjustment helped (fixed it with some views) but its still getting cut-off when the UIScrollView is fairly long. I've been working on this for a while and can't seem to find a fix. Do you have any suggestions? Has anyone ever encountered this issue?
Please help!
Is your scroll view a table view? If so, pretty much only the onscreen content actually exists due to cell reuse. Even if it's a regular scroll view, it's plausible that the OS is making optimizations by not rendering some offscreen elements of the scroll view. If that's true, you may be able to get this to work by programmatically scrolling one screenful at a time and rendering each of those into your context at the right position.