UIView create a inner shadow - iphone

I would like to obtain a UIView like this :
But i don't know, what is the best way to do this ?
Is this the best way: https://stackoverflow.com/a/9214570/1228634 ?

Create the shadow as a transparent layer at a particular size, also create a stretchable image, like this:
UIImage *shadowImage = [UIImage imageNamed:#"shadow.png"];
shadowImage = [shadowImage stretchableImageWithLeftCapWidth:floorf(shadowImage.size.width/2) topCapHeight:floorf(shadowImage.size.height/2)];
Put the image in a UIImageView with contentMode as scale to fit.
Call your view as "sView". You can add the shadow like this:
UIImageView *shadowImgView = [[UIImageView alloc] initWithImage:shadowImage];
shadowImgView.contentMode = UIViewContentModeScaleToFill;
shadowImgView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
shadowImgView.frame = sView.bounds;
[sView shadowImgView];
[shadowImgView release]; // only needed if you aren't using ARC

You can try to use several pictures (as it works for html), but I don't think it is better than your example:
you need 4 small pictures to make a texture for top, left, right and bottom border
you need 4 pictures for your View's corners;
draw to make a border from first 4 images using repeating;
draw corner images.

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.

UIImageView is not showing correctly

At this moment, my program looks like this:
As you can see, the square with the rounded rectangles is an image but it doesn't show very well and am not sure how to solve this... Here is the class: http://pastebin.com/QPXbG1uK
The background window gets added here:
UIImageView* background = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"popupWindowBack.png"]] ;
background.center = CGPointMake(_bigPanelView.frame.size.width/2, _bigPanelView.frame.size.height/2);
[_bigPanelView addSubview: background];
Also what do I need to change if I want a simple view as the background instead of the image?
In Your place I would stop using Center coordinates and specifically set it's frame rectangle:
background.contentMode = UIViewContentModeScaleAspectFit;
background.frame = CGRectMake(10,10,_bigPanelView.frame.size.width-20, _bigPanelView.frame.size.height-20);
In this case - imageview will be 10 pix from top/left/right/bottom.
Remove this:
background.center = CGPointMake(_bigPanelView.frame.size.width/2, _bigPanelView.frame.size.height/2);
If you want to achieve your image fit your UIImageView try this:
background.contentMode = UIViewContentModeScaleAspectFit;
Also you need to set background frame to fit screen size, for example if you adding UIImageView in UIViewController class instance:
background.frame = self.view.frame;
i think your image size is larger then bigPanelView view . plz set the background frame size of the bigPanelView. like
background.frame = bigPanelView.view.frame;

Display Overlay on Image

Using this tutorial: http://www.techotopia.com/index.php/An_Example_iOS_4_iPhone_Camera_Application_%28Xcode_4%29
I have displayed on the UI an image from the photo library. I would like to simply overlay some basic text or a shape (like a square) over the UIImage. Is there an easy way to do this?
Thank you.
Do you have an UIImage only or do you display it using an UIImageView?
If you have an UIImageView then you can just add a UILabel as sub view to your image view.
Assuming your UIImageView is named myImageView ...
// Create and init the label with any rect.
UILabel *myLabel = [[UILabel alloc] initWithFrame:myImageView.frame]; // The lable has the same size as the Image has.
mylabel.text = #"the text";
[myImageView addSubview:myLabel];
//A subview's coordinates are within its superview's coordinates.
mylabel.center = CGPointMake(myImageView.frame.size.width/2,myImageView.frame.size.height/2) // aligning the centers of the views
//An alternative could be transforming the image's center into the coordinate system of its superviews. That code would look smarter but his example is imho easier to understand.
//Setting front, size, alpha, background colour ...
...
You can create a subclass of a UIView, make it transparent, and add an instance of this class, the same size as your image, as a overlay subview on top of the image. Then, when you want to display something on top of your image, call setNeedsDisplay on the transparent subview, and draw whatever you want (colored rectangles, text, etc.) in the drawRect callback of this view.
To make a UIView subclass transparent, add this to the view class initWithFrame method:
[ self setBackgroundColor:[ UIColor clearColor ] ];

Making round corners for a UIImage

In my iPhone application I have to show a UIImage with its all four corners curved so that it looks good on the screen. But my image is a rectangular image which cannot be altered at image level as it comes from a third party.
With UIImageView I can set the frame. Using code, how can I modify my UIImage to have rounded corners?
Any clue?
try this way:
UIImageView *imageView = ...;
imageView.layer.cornerRadius = 7; // change this value as per your desire
imageView.clipsToBounds = YES;

Programmatically prevent UIImageView from autoresizing

I would like to truncate one end of a UIImageView by changing the size of the frame dynamically. Of course, if it autoresizes it won't look 'truncated', but will look shrunk. The former is the effect I would like, the latter not.
So far I've set up the UIImageView in IB and then hooked it up programmatically using IBOutlet. I then placed this in ViewDidLoad, but still get the autoresizing:
[self.stringImageView setAutoresizingMask:UIViewAutoresizingNone];
self.stringImageView.frame = CGRectMake(9.0f, 508.0f, 500.0f, 26.0f);
Any ideas how I can clip my UIImageView instead of having it resize?
EDIT 1
It should also be noted that in IB I have deselected Clip Subviews and Autoresize Subviews.
Use : stringImageView.contentMode = UIViewContentModeCenter; so the image you add to the UIImageView always keeps the same size and the same position in your view.
You need to clip the UIImage object first according to imageview's frame and then set it as image for image view. See also Cropping an UIImage
#implementation UIImage (Resize)
// Returns a copy of this image that is cropped to the given bounds.
// The bounds will be adjusted using CGRectIntegral.
// This method ignores the image's imageOrientation setting.
- (UIImage *)croppedImage:(CGRect)bounds {
CGImageRef imageRef = CGImageCreateWithImageInRect([self CGImage], bounds);
UIImage *croppedImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return croppedImage;
}
In Interface Builder set Mode in the View Tab to "Top" or whatever it should be.
Another more efficient way to go if you only wish to make part of the image visible,
or for example animate its appearance,
is to set the content mode of the UIImageView to UIViewContentModeCenter (or any other alignment) and include it in a UIScrollView.
You will only need to change the frame of the scroll view and your image will be visually cropped without you having to create the cropped image (which would be a very high price if it is for animation purpose).