I want to rotate a subview with the same angle, when its parent view is rotated. How do I achieve this ?
- (void)rotationDetected:(UIRotationGestureRecognizer *)rotationRecognizer {
rotationRecognizer.rotation = M_PI_4;
CGFloat angle = rotationRecognizer.rotation;
duplicateView.transform = CGAffineTransformRotate(duplicateView.transform, angle);
userView.transform = duplicateView.transform;
rotationRecognizer.rotation = 0.0;
}
If you rotate a UIView's parent view the sub view will also rotate in the same way. You do not have to write any special code to make that happen.
Related
I have a UIView in my view. Right now I have a button moving the UIView on it's y axis. Here is my code
CGRect frame2 = self.test22.frame;
frame2.origin.y -= 1.f/[UIScreen mainScreen].scale; //however many pixels to the right..
self.test22.frame = frame2;
But how can I rotate it? Except using the x or y axis. I want to be able to move the UIView by rotation by 1.f.
To Rotate the UIView create the object of UIView (*view) and make transform on it
Lets to rotate the view 90 degree use below code
CGAffineTransform r_transform = CGAffineTransformIdentity;
r_transform = CGAffineTransformRotate(r_transform,DegreeYoRadians(90));
view.transform = r_transform;
Welcome to SO. You want to look at the UIView method animateWithDuration, and the view's transform property. You'd apply a rotation transform to the view in your animation block. Note that if you change a view's transform, you should not read or write the frame property. Instead use the center property to change the position and the bounds.size property if you need to change the size.
Your code might look like this:
[UIView animateWithDuration: .25
animations: ^
{
self.test22.transform = CGAffineTransformMakeRotation(M_PI/2);
CGPoint center = self.test22.center;
center.y -= 1;
self.test22.center = center;
}
];
EDIT:
I have no idea what you mean when you say "I want to be able to move the UIView by rotation by 1.f." Rotating a view is not moving it, it's rotating it. And rotation is expressed as an angle, not a value like "1". Furthermore, the angle is in radians, where π is 180 degrees, π/2 is 90 degrees, and 2π is a full-circle rotation (or no change, since it puts the rotation back at it's original value.) You have to think in terms of fractions of 2π when you do rotations. Or you can use degrees and convert to radians, where:
degrees = radians * 180/π
Also, your code that moves the view will only change the view's position by half a point on retina displays which doesn't make much sense.
I've a UIScrollView with other subviews inside an UIImageWiew and I need to rotate the whole content, so I take this road:
imageView.transform = CGAffineTransformMakeRotation([self.orientation floatValue]);
Good, works perfectly.
Being the ImageView inside a scroll view, I also need to set zoomScale in order to resize image inside, and I do it in this way:
- (void)updateZoom {
const float minZoom = MIN(self.view.bounds.size.width / self.imageView.image.size.width,
self.view.bounds.size.height / self.imageView.image.size.height);
if (minZoom > 1) {
return;
}
self.scrollView.minimumZoomScale = minZoom;
self.scrollView.zoomScale = minZoom;
}
updateZoom has the effect to "reset" initial transformation, so image come back to original orientation.
Generally, each time I modify "zoomScale" property, orientation is restored.
How can I keep both orientation both zoomScale?
I suppose I need to do something in scrollView delegate:
- (void)scrollViewDidZoom:(UIScrollView *)scrollView;
I just put a repo on GitHub that might help you. It is in Swift but it should do
PhotoSlideShow-Swift
I'm working on an app where the main view fills up the whole screen. This main view contains subviews that you could think of as sprites. They wander around using their own code. The logic of how they wander around could have them wandering off screen. What I'd like to do is to resize the main view so that it encloses all the subviews. It's really not the view size that is changing, though. It is the scaling that is changing. Kind of like zooming out of a google maps view. How do I do that? It will be a gesture recognizer that triggers this.
You should do this using a three-level view hierarchy:
top-level view
scaled view
sprite view 0
sprite view 1
sprite view 2
etc.
Set the bounds of the scaled view to encompass the frames of all of the sprite views. Then set the transform of the scaled view so that it fits in the top-level view.
- (void)updateBoundsAndTransformOfView:(UIView *)scaledView {
CGRect scaledBounds = CGRectNull;
for (UIView *spriteView in scaledView.subviews) {
scaledBounds = CGRectUnion(scaledBounds, spriteView.frame);
}
scaledView.bounds = scaledBounds;
// Now scaledView's size is large enough to contain all of its subviews,
// and scaledView's coordinate system origin is at the left edge of the
// leftmost sprite and the top edge of the topmost sprite.
UIView *topLevelView = scaledView.superview;
CGRect topLevelBounds = topLevelView.bounds;
CGFloat xScale =topLevelBounds.size.width / scaledBounds.size.width;
CGFloat yScale = topLevelBounds.size.height / scaledBounds.size.height;
CGFloat scale = MIN(xScale, yScale);
scaledView.transform = CGAffineTransformMakeScale(scale, scale);
scaledView.center = CGPointMake(CGRectGetMidX(topLevelBounds), CGRectGetMidY(topLevelBounds));
}
How can I reset rotation of my View back to zero while keep other transformations on that view unchanged.
I cant use:
[myView setTransform:CGAffineTransformIdentity]
as it will rest all the other transforms too.
Or I just want the frame of the view if its rotation was 0.
myView.transform = CGAffineTransformRotate(myView.transform, -currentRotationAngle);
this will take the current transform, and rotate it to 0 degrees
Edit: i think you will need to rotate by the inverse of your current rotation value, not just set it to 0
To reset the rotation while keeping the transition you could try this code:
CGAffineTransform inverse = CGAffineTransformInvert(myView.affineTransform);
inverse.tx = 0;
inverse.ty = 0;
myView.transform = inverse;
In picture 1, I have a UIView called parentView1 (it is the gray color view). It has subviews (4 in the picture).
Before I applied CGAffineTransformRotate to parentView1, I can drag a view (the red vertical) and drop into parentView1 and the result is as picture 2.
However, if I first do a CGAffineTransformRotate (see code) on parentView1, then drag and drop to add the red vertical view into the parentView1, the red vertical view also gets rotated to the same as the parentView1 (picture 3) immediately as I dropped the vertical view. I do not want it to happen. I need the red vertical view to rest in the same orientation from its original before it was dragged away.
The same effect also happens the other way around: move a subview from parentView1 to outside it boundary if parentView1 has been rotated.
Any suggestion?
Code to rotate parentView1:
self.parentView1.transform = CGAffineTransformRotate(self.parentView1.transform, degreesToRadians(45));
Code to move a view from a parent to another:
-(void)getNewPosition2:(UIView *)viewToConvert parentView:(UIView *)parentViewx superParentView:(UIView *)superParentView
{
CGPoint newPoint = [superParentView convertPoint:viewToConvert.center fromView:parentViewx];
// viewToConvert.layer.position = newPoint;
viewToConvert.center = newPoint;
[viewToConvert removeFromSuperview];
[superParentView addSubview:viewToConvert];
}
Calling the getNewPostition2 method above:
[self getNewPosition2:recognizer.view parentView:self.view superParentView:self.parentView1];
I came up with a solution by using the parentView1's transform matrix to calculate angle for both cases: moving object in and out of parentView1.
For moving object into parentView1:
float angle = (2 * M_PI) - atanf(self.parentView1.transform.b / self.parentView1.transform.a );
viewToConvert.transform = CGAffineTransformRotate(viewToConvert.transform, angle);
For moving object out of parentView1:
float angle = atanf(self.parentView1.transform.b / self.parentView1.transform.a);
viewToConvert.transform = CGAffineTransformRotate(viewToConvert.transform, angle);