How to stretch iOS UITabBarItem background in iOS - objective-c

This is what I'm using now:
tabBarController.tabBar.selectionIndicatorImage = [UIImage imageNamed:#"image.png"];
I have a couple pixels a of a solid color and I would like to stretch it the full width and height of my tabBarItem
How would you do this?

This should help solve your problem
tabBarController.tabBar.selectionIndicatorImage = [[UIImage imageNamed:#"image.png"]
resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
From Apple documentation
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. This technique is often used to create
variable-width buttons, which retain the same rounded corners but whose center region grows
or shrinks as needed. For best performance, use a tiled area that is a 1x1 pixel area in size.
Since we are setting the edge insets to be zero the image will be stetched to cover the entire area.

Related

How can I trim a UIImageView to fit an aspect ratio image

I am using a crop tool in my app and I need to modify a UIImageView so that it fits an image exactly after inserting the image in aspect fit mode.
So an image is selected and added to the UIImageView in aspect fit mode. The problem is that this then leaves "blank space" around the image inside the UIImageView that needs trimming. I was wondering how I could then go and resize the holding UIImageView based upon the image inside.
Is this possible?
The Easy way is simply using the following code on your "imageView"
imageView.contentMode = UIViewContentModeScaleAspectFit;
Assuming you want to cut a "zoomed" section of your image to fit fully into your imageView
check your original image width and height
Assuming width is bigger in size then height , scale the image width to the holder width
center the image on your holder , the width will fit perfectly (section2) and the height will simply be cropped follow above and below the holder.
It turns out that a better approach is to use the following idea.
How to get the size of a scaled UIImage in UIImageView?
Instead of trimming the UIImageView, insert the image and then get the dimensions of the image inside the UIImageView, from there you can then resize the UIImageView to match the dimensions of the image inside.

TapToZoom queries

Has anyone analyzed the sample code for TapToZoom on iPhone.
The program performs 3 things
1. Double Tap, perform zoom
2. Two finger tap, perform zoom out.
and 3. Pinch zoom
I don't understand a small part of it.
The real image size is 1730 × 2430
So there is a scroll view in which an UIImageView of size 1730 × 2430 present. The image is set to Scale to Fit. i.e.
if the image is set to scale to fill the UIImageView which also has the 1730 × 2430, how does the image suddenly on launch fit the screen for the iPhone with reloution 320x460
The Image in the xib in its native size.
But when the app starts off, the image is not in its original size, but fits the scrollview content to fit.
How is this accomplished. I didn't find any piece of code that was doing the same in the app.
Check this piece of code is present in viewDidLoad -
// calculate minimum scale to perfectly fit image width, and begin at that scale
float minimumScale = [imageScrollView frame].size.width / [imageView frame].size.width;
[imageScrollView setMinimumZoomScale:minimumScale];
[imageScrollView setZoomScale:minimumScale];

Using resizableImageWithCapInsets: image for button only works for the state set, other states show a "gap"

When using resizableImageWithCapInsets: to create an image for a UIButton only the normal state (the state set the image with using setBackgroundImage:forState:) works. All other states show a gap instead of the drawn image. UIButton says that if no image is set for a particular state, the normal state image will be used with an overlay for disabled and selected states.
Here is the normal state:
Here is the selected state:
And here is the source image:
It clearly is using the resizable image I provided, but the image is not drawing the resized area. (You can see the left and right edges but the middle area that is to be stretched just isn't drawn).
Interestingly, stretchableImageWithLeftCapWidth:topCapHeight: does work. Now this is a deprecated method in iOS 5, but with the gap being shown in the new API, I may be stuck using it.
I do recognize that I can provide more images for each state but that defeats the purpose I'm trying to achieve of reducing memory footprint plus adds extra dependency on my graphics designer which I'd like to avoid.
// This is the gist of the code being used
UIImage* image = [UIImage imageNamed:#"button.png"];
UIEdgeInsets insets = UIEdgeInsetsMake(image.size.height/2, image.size.width/2, image.size.height/2, image.size.width/2);
image = [image resizableImageWithCapInsets:insets];
[self.button setBackgroundImage:image forState:UIControlStateNormal];
// Even doing the following results in the same behaviour
[self.button setBackgroundImage:image forState:UIControlStateSelected];
You aren't creating your insets properly for the image capping. I've reproduced your issue and corrected it by using the correct insets.
With your current code, you are creating caps of half of the image height and width - this leaves you with a "stretchable" area of 0x0 pixels - so you get nothing in the middle.
Why this isn't showing up as wrong in the normal state of the button I'm not sure - perhaps there is some optimisation built in to UIButton to fix things or auto-strectch if you don't supply a stretchable image, and this is not applied to the other states.
The caps are supposed to define the area of the image that must not be stretched. In the case of your button.png image, this is 6 pixels on the left and right sides, and 16 pixels in from the top and bottom. This isn't quite standard, you should tell your graphics designer that (at least for left-right which is the most common stretching) you should only have a 1px area in the centre, however this does not affect the outcome. If you do have a 1px stretchable area then you can standardise your code by deriving the caps from the image size as you have tried to do in your question (each cap is then (image.size.height - 1) / 2 for top/bottom, same but with width for left/right).
To get the correct images on your button, use the following code for creating the stretchable image:
UIEdgeInsets insets = UIEdgeInsetsMake(16, 6, 16, 6);
image = [image resizableImageWithCapInsets:insets];
I was experiencing problems while using resizable images on iOS5 too. It turns out that if your button is of type "RountedRect" and you manipulate the background images, the resizable images will not behave as expected. (iOS6 handles this ok, presumably by assuming your new button type and adjusting as needed.)

Overlay non transparent Pixels in iOS Cocoa

Is there any way on the iOS SDK to overlay the non-transparent pixels in an image with colored pixels?
Thanks very much to both who answered.
The final solution I implemented used the code mentioned in the accepted answer within the drawRect method of a subclassed UIView, I used the following code to overlay the color:
CGContextSetFillColor(context, CGColorGetComponents([UIColor colorWithRed:0.5 green:0.5 blue:0 alpha:1].CGColor));
CGContextFillRect(context, area);
I think you are probably looking for the blend mode kCGBlendModeSourceAtop. First, draw the UIImage into your view. Then obtain the current graphics context with
CGContext currentCtx = UIGraphicsGetCurrentContext();
Then save the context state, and set the blend mode:
CGContextSaveGState(currentCtx);
CGContextSetBlendMode(currentCtx, kCGBlendModeSourceAtop);
Then you can draw whatever you want to be overlaid over the opaque pixels of the UIImage. Afterward, just reset the context state:
CGContextRestoreGState(currentCtx);
Hope this helps!
You can modify how something is drawn using the blend mode. See http://developer.apple.com/library/ios/#documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html%23//apple_ref/doc/c_ref/CGBlendMode for a full list of the blend modes supported by Core Graphics on iOS. From your description, I think you would be interested in either kCGBlendModeSourceIn, which draws the new content using the old content's alpha value as a mask, or kCGBlendModeSourceAtop, which draws the new content using the old content's alpha as a mask on top of the old content using the new content's alpha value as a mask. You can set the blend mode for all drawing using CGContextSetBlendMode, or you can draw a UIImage with a certain blend mode using -[UIImage drawAtPoint:blendMode:alpha:].

What is the "Mode" property in Interface Builder which offers "Scale to fill", "Aspect fit" etc.?

I'm wondering what the dropdown "Mode" is about? It contains "Scale to fill", "Aspect fit" and so on. I never had to change it so far, still I'm curious what it can be used for. Can somebody explain?
The content mode property of a view tells how its content should be laid out. In the Interface Builder, the various modes can be selected in the Attributes Inspector.
Let's use two image views to see how the various modes work.
Scale to Fill
The image heights and widths are stretched to match the size of the UIImageView.
Aspect Fit
The longest side (either height or width) of the image is stretched to match the view. This makes the image as big as possible while still showing the entire image and not distorting the height or width. (I set the UIImageView background to blue so that its size is clear.)
Aspect Fill
The shortest side (either height or width) of the image is stretched to match the view. Like "Aspect Fit", the proportions of the image are not distorted from their original aspect ratio.
Redraw
Redraw is only for custom views that need to do their own scaling and resizing. We aren't using a custom view, so we shouldn't use Redraw. Notice that here UIImageView just gives us the same result as Scale to Fill, but it is doing more work behind the scenes.
About Redraw, the documentation says:
Content modes are good for recycling the contents of your view, but you can also set the content mode to the UIViewContentModeRedraw value when you specifically want your custom views to redraw themselves during scaling and resizing operations. Setting your view’s content mode to this value forces the system to call your view’s drawRect: method in response to geometry changes. In general, you should avoid using this value whenever possible, and you should certainly not use it with the standard system views.
Center
The image is centered in the view, but the length and width of the image are not stretched.
Top
The top edge of the image is centered horizontally at the top of the view, and the length and width of the image are not stretched.
Bottom
The bottom edge of the image is centered horizontally at the bottom of the view, and the length and width of the image are not stretched.
Left
The left edge of the image is centered vertically at the left of the view, and the length and width of the image are not stretched.
Right
The right edge of the image is centered vertically at the right of the view, and the length and width of the image are not stretched.
Top Left
The top left corner of the image is placed at the top left corner of the view. The length and width of the image are not stretched.
Top Right
The top right corner of the image is placed at the top right corner of the view. The length and width of the image are not stretched.
Bottom Left
The bottom left corner of the image is placed at the bottom left corner of the view. The length and width of the image are not stretched.
Bottom Right
The bottom right corner of the image is placed at the bottom right corner of the view. The length and width of the image are not stretched.
Notes
If the content (in our case the image) is the same size as the view (in our case the UIImageView), then changing the content mode will make no noticeable difference.
See this and this question for a discussion about content modes for views other than UIImageView.
In Swift, to set to set the content mode programmatically you do the following:
imageView.contentMode = UIViewContentMode.ScaleToFill
imageView.contentMode = UIViewContentMode.ScaleAspectFit
imageView.contentMode = UIViewContentMode.ScaleAspectFill
imageView.contentMode = UIViewContentMode.Redraw
imageView.contentMode = UIViewContentMode.Center
imageView.contentMode = UIViewContentMode.Top
imageView.contentMode = UIViewContentMode.Bottom
imageView.contentMode = UIViewContentMode.Left
imageView.contentMode = UIViewContentMode.Right
imageView.contentMode = UIViewContentMode.TopLeft
imageView.contentMode = UIViewContentMode.TopRight
imageView.contentMode = UIViewContentMode.BottomLeft
imageView.contentMode = UIViewContentMode.BottomRight
View Programming Guide goes into details of what you're asking about. If you scroll down to the section called "Content Modes" you'd find what you're looking for.
Basically according to Apple:
"Each view has a content mode that controls how the view recycles its content in response to changes in the view’s geometry [...] the value in the contentMode property determines whether the bitmap should be scaled to fit the new bounds or simply pinned to one corner or edge of the view."
http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way/
should give you the basic ideas very well.