CGAffineTransformMakeTranslation does not translate correctly - ios

I see two different behaviors for CGAffineTransformMakeTranslation between simulator mode and the real device.
(on iOS 8.1)
For an iPhone4, to get CGAffineTransformMakeTranslation to work on the real device, I have to translate by twice the amount.
On the iPhone4s simulator, I have to translate just by the amount with not scaling.
Perhaps I'm missing something obvious but since both have the same number of logical pixels, I shouldn't have to adjust CGAffineTransformMakeTranslation to make translation work.
Here I have a view I'm pulling in and out of view by swiping:
CGRect menuOrigin = self.rootController.containerView.bounds;
switch (direction) {
case UISwipeGestureRecognizerDirectionLeft:
{
NSLog(#"Initial Position: %#", NSStringFromCGPoint(self.rootController.containerView.frame.origin));
NSLog(#"Initial Scale: %f", [self contentScaleFactor]);
NSLog(#"Initial Center: %#", NSStringFromCGPoint([self center]));
CGAffineTransform transform = CGAffineTransformMakeTranslation(-1.0 * widthToSlide, 0);
self.rootController.containerView.transform = transform;
[UIView animateWithDuration:0.4 animations:^{
self.rootController.containerView.transform = transform;
[self.rootController.containerView layoutIfNeeded];
} completion:^(BOOL finished) {
NSLog(#"Final Position: %#", NSStringFromCGPoint(self.rootController.containerView.frame.origin));
NSLog(#"Final Scale: %f", [self contentScaleFactor]);
NSLog(#"Final Center: %#", NSStringFromCGPoint([self center]));
}];
}
break;
case UISwipeGestureRecognizerDirectionRight:
{
CGAffineTransform transform = CGAffineTransformMakeTranslation(0, 0.0);
[UIView animateWithDuration:0.4 animations:^{
self.rootController.containerView.transform = transform;
[self.rootController.containerView layoutIfNeeded];
} completion:^(BOOL finished) {
}];
}
default:
break;
}
[self.rootController.containerView setNeedsDisplay];
[self setNeedsDisplay];
NSLog goes like this for the iPhone4 real device:
2015-10-15 01:12:37.547 Local[5307:60b] swipeLocalPull adjusting width 183
2015-10-15 01:12:37.556 Local[5307:60b] Screen size: {320, 480}
2015-10-15 01:12:37.559 Local[5307:60b] Initial Position: {0, 66}
2015-10-15 01:12:37.974 Local[5307:60b] Final Position: {-91.5, 66}
and for the iPhone4s iOS 8.1 simulator:
2015-10-15 01:19:19.479 Local[56380:3061577] swipeLocalPull adjusting width 183
2015-10-15 01:19:19.480 Local[56380:3061577] Screen size: {320, 480}
2015-10-15 01:19:19.480 Local[56380:3061577] Initial Position: {0, 66}
2015-10-15 01:19:19.886 Local[56380:3061577] Final Position: {-183, 66}
The simulator is translated correctly. Notice, the real device translated only half way to -91.5. Why is this and how can I detect or compensate for this. Sorry if this question has been asked before but I could not find the root cause for this behavior. I only care about x translation at this moment.
Anyone have clues for this behavior.?
Update
By request, here's a few extra outputs:
---iPhone4 values---
2015-10-15 17:20:59.591 Local[5617:60b] swipeLocalPull adjusting width 183
2015-10-15 17:20:59.596 Local[5617:60b] Screen size: {320, 480}
2015-10-15 17:20:59.599 Local[5617:60b] Initial Position: {0, 66}
2015-10-15 17:20:59.601 Local[5617:60b] Initial Scale: 2.000000
2015-10-15 17:20:59.603 Local[5617:60b] Initial Center: {201, 99}
2015-10-15 17:21:00.015 Local[5617:60b] Final Position: {-91.5, 66}
2015-10-15 17:21:00.018 Local[5617:60b] Final Scale: 2.000000
2015-10-15 17:21:00.037 Local[5617:60b] Final Center: {201, 99}
---iPhone4s Simulator---
2015-10-15 17:39:59.850 Local[57069:3104390] swipeLocalPull adjusting width 183
2015-10-15 17:39:59.851 Local[57069:3104390] Screen size: {320, 480}
2015-10-15 17:39:59.851 Local[57069:3104390] Initial Position: {0, 66}
2015-10-15 17:39:59.851 Local[57069:3104390] Initial Scale: 2.000000
2015-10-15 17:39:59.851 Local[57069:3104390] Initial Center: {201, 99}
2015-10-15 17:39:59.852 Local[57069:3104390] Final Position: {-183, 66}
2015-10-15 17:39:59.852 Local[57069:3104390] Final Scale: 2.000000
2015-10-15 17:39:59.852 Local[57069:3104390] Final Center: {201, 99}
They both seem to be at #2x scale so I expect the same code to work for both.
Working Code
I got it to work with the following(if someone explains why, then I'll just mark that as the answer):
switch (direction) {
case UISwipeGestureRecognizerDirectionLeft:
{
NSLog(#"Initial Position: %#", NSStringFromCGPoint(self.rootController.containerView.frame.origin));
NSLog(#"Initial Scale: %f", [self contentScaleFactor]);
NSLog(#"Initial Center: %#", NSStringFromCGPoint([self center]));
CGPoint currentPos = self.rootController.containerView.center;
currentPos.x -= widthToSlide;
[UIView animateWithDuration: .4
delay: 0
options: (UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)
animations:^{
self.rootController.containerView.center = currentPos;
}
completion:^(BOOL finished) { }
];
}
break;
case UISwipeGestureRecognizerDirectionRight:
{
CGPoint currentPos = self.rootController.containerView.center;
currentPos.x += widthToSlide;
[UIView animateWithDuration: .4
delay: 0
options: (UIViewAnimationOptionCurveLinear | UIViewAnimationOptionAllowUserInteraction)
animations:^{
self.rootController.containerView.center = currentPos;
}
completion:^(BOOL finished) { }
];
}
default:
break;
}
[self.rootController.containerView setNeedsDisplay];
[self setNeedsDisplay];

Related

Scaling down the width of a view after doing rotation by using CGAffineTransformScale

I have drawn a view(black rectangle) straight to the x-axis then I am applying some rotation by using CGAffineTransformMakeRotation.Please see image 1 after rotation.
After this I need to reduce the width from that rotated position.
For that I am using CGAffineTransformScale but image is not scaling down along the slope.Please see image 2.
If I change width from bound property then it works fine.
Any idea why CGAffineTransformScale behaves like that.
Below is my sample code.
**__block CGAffineTransform rotationTransform;
rotationTransform = CGAffineTransformMakeRotation(angle);
lineview.transform = rotationTransform;
[UIView animateWithDuration:10 animations:^{
CGAffineTransform finalTransform = CGAffineTransformScale(lineview.transform, 0.4, 1);
lineview.transform = finalTransform;
} completion:^(BOOL finished) {
}];
Try this to move the frame and change the width :)
VIEW.frame = CGRectMake(0,39, 320, 111);
This is the format
CGRectMake(CGFloat x, CGFloat y, CGFloat width, CGFloat height)

Scale animation in background from another anchorPoint

Ive done a Scaling animation for background image with an arrow in it,well by scaling the image(it includes the arrow) meaning its a whole background. it scales from the center of the background. but i want to start scaling from the center of arrow.
i want to achieve this :
Then to become with scale:
What i have to change in my code:
self.blueBackground.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1, 1);
[UIView animateWithDuration:5 animations:^{
self.blueBackground.transform = CGAffineTransformScale(CGAffineTransformIdentity, 30, 30);
} completion:^(BOOL finished) {
}];
With my current code the scale start from center of background so the arrow end up at the right (out the bounds of screen).
Try something like this:
- (void)animateArrow
{
self.blueBackground.transform = CGAffineTransformIdentity;
[UIView animateWithDuration:5 animations:^{
ScaleViewAboutPointInBounds(self.blueBackground, arrowCenter, 30);
} completion:^(BOOL finished) {
}];
}
static void ScaleViewAboutPointInBounds(UIView *view, CGPoint point, CGFloat scaleAmount)
{
CGFloat xAnchor = view.layer.anchorPoint.x * CGRectGetWidth(view.bounds);
CGFloat yAnchor = view.layer.anchorPoint.y * CGRectGetHeight(view.bounds);
CGFloat xOffset = point.x - xAnchor;
CGFloat yOffset = point.y - yAnchor;
CGAffineTransform shift = CGAffineTransformMakeTranslation(-xOffset, -yOffset);
CGAffineTransform unshift = CGAffineTransformMakeTranslation(xOffset, yOffset);
CGAffineTransform scale = CGAffineTransformMakeScale(scaleAmount, scaleAmount);
view.transform = CGAffineTransformConcat(shift, CGAffineTransformConcat(scale, unshift));
}
It's probably more general than what you need, and you could do it simpler, but this should work too. Just change the point to something that looks like the center of the arrow.

Window has weird frame and offset after rotation on iOS 8

On iOS 8, when launching the app in landscape mode, I get weird values for the key window's frame after a rotation:
// Before rotation (landscape)
{{0, 0}, {768, 1024}}
// After rotation (portrait)
{{-256, 0}, {1024, 768}}
Code:
NSLog(#"%#", NSStringFromCGRect(UIApplication.sharedApplication.keyWindow.frame));
Where does the X offset come from, and why are the frame values inverted (should be width=768 in landscape mode)?
I was having this problem and fixed it by using the fixedCoordinateSpace.bounds. Heres a quick example.
Observe status bar changes in the window.
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(statusBarFrameOrOrientationDidChanged) name:UIApplicationDidChangeStatusBarOrientationNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(statusBarFrameOrOrientationDidChanged) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
}
return self;
}
Than rotate the window and resize the windows frame.
- (void)statusBarFrameOrOrientationDidChanged {
CGRect rect = ({
CGRect rect;
if ([[[UIDevice currentDevice] systemVersion] intValue] <= 7) {
rect = [UIScreen mainScreen].bounds;
} else {
id<UICoordinateSpace> fixedCoordinateSpace = [UIScreen mainScreen].fixedCoordinateSpace;
rect = fixedCoordinateSpace.bounds;
}
rect;
});
CGAffineTransform transform = CGAffineTransformMakeRotation(({
CGFloat angle;
switch ([UIApplication sharedApplication].statusBarOrientation) {
case UIInterfaceOrientationPortraitUpsideDown:
angle = M_PI;
break;
case UIInterfaceOrientationLandscapeLeft:
angle = -M_PI_2;
break;
case UIInterfaceOrientationLandscapeRight:
angle = M_PI_2;
break;
default:
angle = 0.0f;
break;
}
angle;
}));
if (!CGAffineTransformEqualToTransform(self.transform, transform)) {
self.transform = transform;
}
if (!CGRectEqualToRect(self.frame, rect)) {
self.frame = rect;
}
}

TableViewHeader animation not moving header

I have a TableViewHeader and want to animate it so it looks like it is shrinking when I have rows in my table. I have tried numerous things but it doesn't want to move. The console output shows it was resized but I still see it as normal on the screen.
Why is the animation not working? Am I overlooking something?
- (void)setProperHeader
{
UIView *tempView = nil;
CGRect offsets;
if ([appointmentsList count] == 0) {
NSLog(#"List Count 0");
tempView = [[self.storyboard instantiateViewControllerWithIdentifier:#"ExistingAppointmentsViewController"] viewWithTag:400];
offsets = CGRectMake(tempView.frame.origin.x, tempView.frame.origin.y, tempView.frame.size.width, tempView.frame.size.height);
tempView.frame = CGRectMake(offsets.origin.x, offsets.origin.y, offsets.size.width, 0);
} else {
NSLog(#"List Count is %i", [appointmentsList count]);
tempView= self.tableView.tableHeaderView;
offsets = CGRectMake(tempView.frame.origin.x, tempView.frame.origin.y, tempView.frame.size.width, 0);
}
NSLog(#"TableView Frame: %#", NSStringFromCGRect(self.tableView.tableHeaderView.frame));
NSLog(#"Offsets %#", NSStringFromCGRect(offsets));
NSLog(#"Temp: %#", tempView);
// if (tempView != self.tableView.tableHeaderView) {
[self.tableView setTableHeaderView:tempView];
[UIView animateWithDuration:1.0f
animations:^{
tempView.frame = offsets;
}
completion:^(BOOL finished) {
NSLog(#"Complete tempView: %#", tempView);
NSLog(#"Complete tableHeader: %#", self.tableView.tableHeaderView);
[self.tableView setNeedsLayout];
[self.tableView reloadData];
}];
// }
}
The [self.tableView setNeedsLayout] was added in as a test to see if that would make it work.
Console Output
2013-09-25 16:04:32.301 App[63910:a0b] List Count is 2
2013-09-25 16:04:32.301 App[63910:a0b] TableView Frame: {{0, 0}, {320, 91}}
2013-09-25 16:04:32.301 App[63910:a0b] Offsets {{0, 0}, {320, 0}}
2013-09-25 16:04:32.302 App[63910:a0b] Temp: <UIView: 0xa568560; frame = (0 0; 320 91); autoresize = W+H; tag = 400; layer = <CALayer: 0xa5685c0>>
2013-09-25 16:04:33.313 App[63910:a0b] Complete tempView: <UIView: 0xa568560; frame = (0 0; 320 0); autoresize = W+H; tag = 400; layer = <CALayer: 0xa5685c0>>
2013-09-25 16:04:33.313 App[63910:a0b] Complete tableHeader: <UIView: 0xa568560; frame = (0 0; 320 0); autoresize = W+H; tag = 400; layer = <CALayer: 0xa5685c0>>

iOS CAlayer Orientation AVCaptureVideoPreviewLayer doesn't rotate

Summary:
I can't force the CALayer to respond correctly to orientation changes.
Whenever I try to use cgaffinetransform I am getting weird results (layer is not centered).
Any help will be appreciated!
thanks,
Process
I am adding a preview of video using AVCaptureVideoPreviewLayer subclass. When device is in a portrait orientation everything looks fine. The problem appears when device is rotated to landscape orientation (left or right) or portrait upside down.
I am adding a preview of video using AVCaptureVideoPreviewLayer subclass. When device is in a portrait orientation everything looks fine. The problem appears when device is rotated to landscape orientation (left or right) or portrait upside down.
I am adding a preview layer using the following code:
CGRect layerRect = [[[self view] layer] bounds];
[[[self captureManager] previewLayer] setBounds:layerRect];
[[[self captureManager] previewLayer]setFrame:CGRectMake(0, height, width, height)];
[[[self captureManager] previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect),CGRectGetMidY(layerRect))];
And it is displayed properly in portrait mode.
When I try to rotate the device, preview layer behaves weird. It seems like it doesn't resize itself, and it doesn't rotate correctly.
I tried to fix it by adding the following method
-(void)rotateLayer{
CALayer * stuckview = [[self captureManager] previewLayer];
CGRect layerRect = [[[self view] layer] bounds];
UIDeviceOrientation orientation =[[UIDevice currentDevice]orientation];
switch (orientation) {
case UIDeviceOrientationLandscapeLeft:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI+ M_PI_2); // 270 degress
NSLog(#"Landscape Left");
[stuckview setPosition: CGPointMake(self.view.bounds.size.width /2.0, self.view.bounds.size.height /2.0)];
break;
case UIDeviceOrientationLandscapeRight:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI_2); // 90 degrees
NSLog(#"Landscape Right");
[stuckview setPosition: CGPointMake(self.view.bounds.size.width /2.0, self.view.bounds.size.height /2.0)];
break;
case UIDeviceOrientationPortraitUpsideDown:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI); // 180 degrees
NSLog(#"Landscape Upside down");
break;
default:
stuckview.affineTransform = CGAffineTransformMakeRotation(0.0);
break;
}
float h1 = stuckview.frame.size.height;
float w1 = stuckview.frame.size.width;
if(UIDeviceOrientationIsPortrait(orientation))
{
stuckview.position =CGPointMake(h1/2.0, w1/2.0);
NSLog(#"Portrait");
}
else{
stuckview.position =CGPointMake(w1/2.0, h1/2.0);
NSLog(#"Portrait");
}
}
After adding the method above I can see a progress. Now layer rotates correctly reflecting current device orientation and it's displayed correctly in landscape mode, but NOT in portrait mode.
The layer is not positioned correctly, it isn't centered on the screen (look at the screenshot). To see what's happening I added following debug statements:
CALayer * stuckview = [[self captureManager] previewLayer];
CGRect layerRect = [[[self view] layer] bounds];
float h = stuckview.bounds.size.height;
float w = stuckview.bounds.size.width;
float x = stuckview.bounds.origin.x;
float y = stuckview.bounds.origin.y;
float h1 = stuckview.frame.size.height;
float w1 = stuckview.frame.size.width;
float x1 = stuckview.frame.origin.x;
float y1 = stuckview.frame.origin.y;
NSLog(#"%f %f %f %f ", h,w,x,y );
NSLog(#"%f %f %f %f ", h1,w1,x1,y1 );
NSLog(#"Anchor Point: %f %f",stuckview.anchorPoint.x, stuckview.anchorPoint.y);
NSLog(#"Position: %f %f",stuckview.position.x, stuckview.position.y);
CGAffineTransform at = stuckview.affineTransform;
NSLog(#"Affine Transform After : %f %f %f %f %f %f %f", at.a,at.b, at.c, at.d, at.tx,at.tx, at.ty);
And get the following output:
2012-09-30 13:25:12.067 RotatePreviewLayer[2776:907] 1024.000000 768.000000 0.000000 0.000000
2012-09-30 RotatePreviewLayer[2776:907] 1024.000000 768.000000 128.000000 -128.000000
2012-09-30 13:25:12.070 RotatePreviewLayer[2776:907] Portrait
2012-09-30 13:25:12.072 RotatePreviewLayer[2776:907] Anchor Point: 0.500000 0.500000
2012-09-30 13:25:12.074 RotatePreviewLayer[2776:907] Position: 512.000000 384.000000
2012-09-30 13:25:12.076 RotatePreviewLayer[2776:907] Affine Transform after: -1.000000 0.000000 -0.000000 -1.000000 0.000000 0.000000 0.000000
Notice the second line of the debug output. The frame of the preview layer is moved by 128,-128.
Can anyone explain me why is this happening and how to fix the orientation issues with the preview layer?
thank you,
Janusz
What about this?
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
_videoPreviewLayer.connection.videoOrientation = toInterfaceOrientation;
}
This the method I use in the view controller to maintain the orientation of the capture layer so that it is always right-side-up:
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
if (_previewLayer.connection.supportsVideoOrientation)
{
switch (toInterfaceOrientation)
{
case UIInterfaceOrientationPortrait:
{
_previewLayer.connection.videoOrientation = AVCaptureVideoOrientationPortrait;
break;
}
case UIInterfaceOrientationPortraitUpsideDown:
{
_previewLayer.connection.videoOrientation = AVCaptureVideoOrientationPortraitUpsideDown;
break;
}
case UIInterfaceOrientationLandscapeLeft:
{
_previewLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeLeft;
break;
}
case UIInterfaceOrientationLandscapeRight:
{
_previewLayer.connection.videoOrientation = AVCaptureVideoOrientationLandscapeRight;
break;
}
}
}
A little wordy, but safe even if either enumeration ever changes in the future.
I am still not sure what's causing the problem but I managed to fix it. Here is how I did it:
in viewDidLoad I am adding a layer:
CGRect layerRect = [[[self view] layer] bounds];
[[[self captureManager] previewLayer] setBounds:layerRect];
[[[self captureManager] previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect),CGRectGetMidY(layerRect))];
[[[self view] layer] addSublayer:[[self captureManager] previewLayer]];
Then I am adding call to the rotateLayer method to didRotate
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
[self rotateLayer];
}
and finally the rotateLayer method looks like:
-(void)rotateLayer{
CALayer * stuckview = [[self captureManager] previewLayer];
CGRect layerRect = [[[self view] layer] bounds];
UIDeviceOrientation orientation =[[UIDevice currentDevice]orientation];
switch (orientation) {
case UIDeviceOrientationLandscapeLeft:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI+ M_PI_2); // 270 degress
break;
case UIDeviceOrientationLandscapeRight:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI_2); // 90 degrees
break;
case UIDeviceOrientationPortraitUpsideDown:
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI); // 180 degrees
break;
default:
stuckview.affineTransform = CGAffineTransformMakeRotation(0.0);
[stuckview setBounds:layerRect];
break;
}
[stuckview setPosition:CGPointMake(CGRectGetMidX(layerRect),CGRectGetMidY(layerRect))];
}
I still don't understand why it works in this way. If anyone can explain it will be great.
#Janusz Chudzynski here is the detailed explanation what rotateLayer method does
This method is created after examine how different orientation affect the previewLayer so creater has checked when orientation is in LandscapeLeft then it should be 270 degrees rotated to make it in correct position for that he has used
stuckview.affineTransform = CGAffineTransformMakeRotation(M_PI+ M_PI_2);
M_PI 3.14159265358979323846264338327950288 // pi = 180 degree
+
M_PI_2 1.57079632679489661923132169163975144 // pi/2 = 90 degree
// Total = 270 degree
so creater has noticed that if I will rotate previewLayer to 270 degrees when its in LandscapeLeft then it will be in correct position just like that he has rotate previewLayer for every rotation possible
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
previewLayer.orientation = toInterfaceOrientation;
}
I'm with #Siegfault, although I also found that when my view loads in landscape orientation on the iPad initially, the orientation is still in correct. To fix, I call that same delegate method in viewDidAppear: with the current interfaceOrientation:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self willRotateToInterfaceOrientation:self.interfaceOrientation duration:0.0];
}
The answer using willRotateToUserInterfaceOrientation works fine, except that that method has been deprecated. So if you're able to use iOS 9, then here's the way to do it, in Swift:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
let newOrientation = UIDevice.currentDevice().orientation
switch newOrientation {
case .LandscapeLeft:
self.capturePreviewLayer?.connection.videoOrientation = .LandscapeLeft
case .LandscapeRight:
self.capturePreviewLayer?.connection.videoOrientation = .LandscapeRight
case .Portrait, .Unknown, .FaceUp, .FaceDown:
self.capturePreviewLayer?.connection.videoOrientation = .Portrait
case .PortraitUpsideDown:
self.capturePreviewLayer?.connection.videoOrientation = .PortraitUpsideDown
}
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}
// layout iOS 8+ animated
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
NSString *timingFunc = nil;
switch ( [context completionCurve] )
{
case UIViewAnimationCurveEaseIn: timingFunc = kCAMediaTimingFunctionEaseIn; break;
case UIViewAnimationCurveEaseInOut: timingFunc = kCAMediaTimingFunctionEaseInEaseOut; break;
case UIViewAnimationCurveEaseOut: timingFunc = kCAMediaTimingFunctionEaseOut; break;
case UIViewAnimationCurveLinear: timingFunc = kCAMediaTimingFunctionLinear; break;
}
[CATransaction begin];
[CATransaction setAnimationDuration:[context transitionDuration]];
[CATransaction setAnimationTimingFunction:[CAMediaTimingFunction functionWithName:timingFunc]];
[self updatePreviewLayer];
[CATransaction commit];
UIInterfaceOrientation toOrientation = [[UIApplication sharedApplication] statusBarOrientation];
// layout ui if needed
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
}];
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
- (void)updatePreviewLayer
{
CGAffineTransform transform = CGAffineTransformIdentity;
switch ( UIDevice.currentDevice.orientation )
{
case UIDeviceOrientationLandscapeLeft:
transform = CGAffineTransformRotate(transform, -M_PI_2);
break;
case UIDeviceOrientationLandscapeRight:
transform = CGAffineTransformRotate(transform, M_PI_2);
break;
case UIDeviceOrientationPortraitUpsideDown:
transform = CGAffineTransformRotate(transform, M_PI);
break;
default:
break;
}
preview.affineTransform = transform;
preview.frame = self.view.bounds;
}

Resources