IOS Affine Transforms - ios

Does an affine transform reposition the content within the view or transform the view's output?
In my experiments, it appears to be the latter. If I apply a translation moving the contents off the view the right, I do not appear to be able to draw in the area within the view to the left.
As requested: I would like to be able to create a scrolling view that rotates. Imagine viewing part of a globe viewed parallel to the axis. The content has to rotate with scrolling.
If I use an affine transform, it appears that the view display is transformed, not the content within the view. If I scroll the content to the right using an affine transform, I get a black area to the left visible in the view that I cannot draw in.
I am trying to confirm whether my interpretation of what is happening is correct. If so, I need to try a different approach.

Related

IOS Image Rotational Scrolling

I have chart images that are conical projections. Whenever the chart position moves, I need to rotate the chart. Imagine viewing a globe from above. The change in rotation is generally less than 1 degrees for a full screen of scrolling.
I am currently doing this in an image view within a scroll view, redrawing the images when the position changes. Any small change in position requires a complete redraw.
Is there a way to have IOS rotate the images within the layer without having to redraw them.
I am imaging something like in the maps app where you can scroll-rotate your course.
Another way of looking at it would be to have something like a scroll view that can scroll up/down or rotate its contents around an axis that may be way off the top of the screen.

iOS Quartz 2D How to expand layer beyond screen frame

Here is a picture:
Is there a way to expand layer (the area where you draw), to be larger.
At first i thought that (0,0) is the center, but it seems that it is a starting point for layer.
I was planning to draw content at (0,0) then to translate it as necessary.
Or, must i draw whatever i have in center of layer (width/2, height/2) and then translate as necessary?
EDIT_01:
The offset of layer is made by panning gesture recognizer. That is on purpose, since app must have panning of content.
Answers
At first i thought that (0,0) is the center, but it seems that it is a starting point for layer
(0,0) in iOS begins at the top left of the layer, and gets greater going right and down. In OS X, (0,0) begins in the bottom left, and gets greater going right and up.
Is there a way to expand layer (the area where you draw), to be larger
The question I have is, do you need to? This can have performance issues, as you're rendering and storing drawing data when you don't really need to, causing more memory to be used. It looks like your layer is filling the screen correctly, it's just translated incorrectly. If you move it to the correct place, you shouldn't need to expand the layer off screen.
This doesn't mean you can't translate other layers off screen, of course you can. But really you don't want to expand the size of your drawing area to expand off screen.
Must i draw whatever i have in center of layer (width/2, height/2) and then translate as necessary?
If you want them drawn into the center, then yes. You can create your own method to translate your own co-ordinate space into the co-ordinate space of the layer, to make this easier for you.
Documentation
I'd suggest reading this, to get a greater grasp of the geometry workings of CALayer:
https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/Layers.html#//apple_ref/doc/uid/TP40006082-SW1
...and this to get an understanding of drawing techniques:
https://developer.apple.com/library/ios/#documentation/graphicsimaging/conceptual/drawingwithquartz2d/dq_layers/dq_layers.html

How can I reproduce a "box" transition animation in iOS?

I want to build an animated transition between two view controllers in iOS, resembling the "Box" transition in PowerPoint or the "Reflection" transition in Keynote.
You can see it here, at 2:10:
http://youtu.be/1fLQg5hFQQg?t=2m10s
What's the best way to do this?
Thanks!
That would be a complex animation to recreate. You'd need to use a CAAnimationGroup that grouped several different animations running at once. You'd want to animate a rotation around the y axis with the center of rotation lifted off the screen, on both the view controller that is animating away and the view that your are animating into place.
You would have to tweak the transform to make it draw with perspective (you add a small value to the .m34 record in the transform). That's because CA animations are orthographic by default (they don't show perspective.)
The reflections could be created using a special subclass of CALayer that lets you create duplicates of a layer. I'm blanking on the name of that layer subclass at the moment. You'd set up 1 duplicate with a scale of -1 on the y axis to flip it upside down, and a darkening effect. I've never done it myself, but I've seen several examples in books and online.

Correcting blurry text after a CGAffineTransformMakeScale

I have multiple views with many UILabels on the views. (all constructed in Interface Builder).
I am then trying to create a "smaller" replica of my view when you pinch the screen.
To do this I apply:
view.transform = CGAffineTransformMakeScale(.5, .5);
and then I also adjust the frame of view.
The problem is that after the transformation, the text in all of my UILabels becomes "blurry". It doesn't stay pixel perfect as it is in full-scale view.
Is there a way to increase the pixelation of the labels after the transformation?
Applying a transform to a UIView or CALayer merely scales the rasterized bitmap of that layer or view. This can lead to blurriness of the resulting UI element, because they aren't re-rendered at that new scale.
If you really want your text or images to be crisp at the new scale factor, you're going to need to manually resize them and cause them to redraw instead of applying a transform. I described one way that I did this with a UIView hosted in a UIScrollView in this answer.
You might be able to create a single method that traverses your view hierarchy for your one main view, recursively reads each subview's frame, scales that down, and then forces a redraw of its contents. Transforms are still great to use for interactive manipulation or animation, but you can then trigger a full manual scaling and redraw at the end of the manipulation or animation.

Rotating a UIView; How to prevent clipping during rotation?

So let's say I have a UIView that in its standard configuration spans the full width and height of its container. For the purposes of this question, let's say that its dimensions are 320x400. Suppose that this view contains content that may be (and typically is) larger than its standard dimensions (so it scrolls through content).
Now if this UIView has a UIRotationGestureRecognizer associated with it that is used to rotate the view using its transform property, how do I ensure that its frame size/drawable area is always sufficiently large for its current orientation (by "sufficiently large" I mean that the rendered content should always extend out to the original bounds, and not be clipped prior to reaching the edge of the original bounds)? For instance, if I rotate it 90 degrees the view needs to understand that its "width" may now consume up to 400 pixels, while its height is constrained to 320 pixels.
Note that I don't want to scale the view as part of the rotation operation. Any "additional" space that becomes available due to the current rotation should be used to display additional content, if available, and not to simply display the same content at a higher zoom level.
You don't want any empty spaces to appear when rotating. The solution is to have a subview containing a background which is sufficiently large enough to cover the entire viewport during rotation. I'd say a 400 by 400 view should do. This view can either be the parent of your contentview, but that'll give you a bit of a positioning hassle.
Easier would be to add a subview on your currentview. Put the (large) background on this subview, make sure this view is at the bottom of the view stack and on your currentview put clipsToBounds=NO.
Beware though that disabling clipping can have a performance impact especially if your view hierarchy becomes complex.

Resources