Stretchable UIImage and CGAffineTransform - iphone

I've got a UIScrollView whose zoom behavior I want to confine to the horizontal axis. I've accomplished that through using a custom UIView as the viewForZoomingInScrollView: and overriding setTransform:. So far so good – the view only zooms horizontally.
One catch: The container view includes some stretchable UIImage instances in UIImageViews. Obviously, with the transform in effect, the images distort.
What's the best bet for either redrawing the view so that the images aren't distorted, or, zooming the view in such a way as to not require transforms in the first place?
Thanks for any help you can offer.

You sure way of achieving this is to make your UIImageView into a custom UIView, and have its drawRect: code do the right thing: draw both stretched and unstretched elements.

Related

Display UIImageView image over it's parent UIImageView

I have an easy task but still don't get how to make it work.
I have a UIView, inside the UIView i have the main UIImageView of half UIView size (half display).
And inside of the UIImageView i have two UIImageViews with images.
I need to pan the internal UIImageViews, and that's not a problem but the problem is that it will not go above the parent UIImageView borders. Same happens when i use two UIImage instead of UIImageView.
I have tried to bring it on top (bringSubviewToFront) but it does not help because its parent controller not the UIView. And the two internal UIImageViews must be a part of the main UIImageView because the main UIImageView can move, so i move all together.
Any help appreciated.
Although the correct solution is to have a superview that's the correct size, you can always "see" what lies outside of the bounds by setting clipsToBounds to NO on the parent UIImageView.
This will draw the subviews even if they lie outside the bounds of the superview. Keep in mind though, that the parts that are outside the bounds will not react to touches, i.e the hit box is always clipped.
You can have one parent view, containing large image and two smaller as siblings. Then you an control position of two images freely without attaching them to larger image.
Like this:
-Parent View (the largest, within which all images aare displayed)
- Large image
- small image
- small image
Now small images are free, and you can align them to large image whenever you want!

How can I make a UIView that is stretchable by its corners?

I'd like to have a UIView where the user can select each of the four corners and stretch the view by independently moving them.
How would I implement such a view?
To do this, you will need to subclass UIView and handle touch events manually. When you get a touch event, you will have to do some math and then set the frame of the view to the new size. I'd recommend making the background image a stretchable image using stretchableImageWithLeftCap:topCap. It shouldn't actually be that hard.

how to draw an UIImageView into -drawRect of another view?

I have several UIImageView objects which have been rotated and scaled. Because they are just background images, and represent an non-highlighted-state, I want to draw them to the canvas of the view so that I can get rid of them in memory. The view has a big bitmap anyways, so it would save a lot of memory to put them in there rather than adding as subview.
It seems I can only call something like -drawInRect for an UIImage, but how about an UIImageView with transforms on it? Oh yes, and it's positioned with frame origin.
I just want to draw it to another UIView's bitmap the same way as it appears when adding as subview.
Using drawInRect: with a rect of different origin and size of the image, you can effectively make any scaling and translation you want. You can also handle rotations with the [CGContextRotateCTM][1] function (CTM = current transformation matrix). There are other CGContext..CTM functions as well, so you have multiple approaches.

Border image on UIView

I want to have a UIView subclass that has a border image, but I don't want or care about this 'new' frame/bounds around the border image itself.
What I wanted to do was just use drawRect and draw outside of the rect but all drawing is clipped and I don't see a way to not clip drawing outside of this context rect.
So now I have added a sublayer to the views layer, set [self clipsToBounds] on the view and override setFrame to control my sublayers frame and always keep it at the proper size (spilling over the views frame by 40px).
The problem with this is that setFrame on a uiview by default has no animation but seTFrame on a calayer does.
I cant just disable the animations on the calayers setFrame because if I were to call setFrame on the uiview inside a uiview animation block the calayer would still have its animation disabled.
The obvious solution is to look up the current animationDuration on the uiview animation and set a matching animation on the sublayer, but I don't know if this value is available. And even if it is, I'm afraid that calling an animation from within another animation is wrong.
Unfortunately the best solution is to not use a calayer at all and just add a uiview as a subview and draw into that just like I am drawing into my layer, and hope that with autoresizingMask set to height and width that everything will 'just work'. Just seems like unnecessary overhead for such a simple task.
My solution would be to override the initWithFrame: to add the surrounding border pixels and contain the content in a subview. It probably is unneccesary overhead but definietly the "cocoa" route. It's probably going to be easier in the end too since a subview structure will allow you to edit the content seperatly from the border so you dont have to redraw the border when you redraw the content. And keeping them seperate simply makes sense from a OOP perspective.
The clipsToBounds route is probably the easiest route besides the subview structure but managing the border and content in one drawing cycle and in one object will probably be a lot more work so it'll be worth the overhead.
Excuse any typos, typed this from my iPhone.

Apply barrel distortion to UIView

I've got a UIScrollview which fills a landscape screen, which contains a small tree of UIViews around inside it which I can scroll horizontally. I'd like to apply a barrel distortion to the scrollview, so that as the subviews move from the outside to the centre of the scrollview, they change shape.
What is a good what to go about applying distortions like this?
Is there a way to override drawRect for the scroll view, draw onto a bitmap, distort it, then draw that to the ScrollView's context instead? Or are there built in APIs to do this sort of distortion?
(source: arielnet.com)
You could get close to this effect by properly transforming the layers for each of your UIViews. Using a CATransform3D, you can rotate and translate each of the layers in 3-D, as well as apply a perspective effect. For your case, you can translate each of your UIView layers so that they are like a carousel, with the middle view forward and straight-on to the screen, and the side layers tilted and recessed slightly from the screen. This would not cause a curvature of the layers themselves (they will still be drawn as rectangles), but if you apply a transform on the main view's layer to create a perspective effect you should be able to get very close.
For an example of this kind of 3-D positioning of layers, I recommend this example where a full 3-D maze is constructed out of CALayers.
As far as the scroll view goes, you probably will have to do custom touch handling for this. You might be able to get by with respinding to the UIScrollViewDelegate methods like scrollViewDidScroll:, but I've not tried this myself.