我有一个自定义转场,我正在尝试执行与标准“Cover Vertical”转场相反的操作。我认为这应该有效:
UIView *srcView = ((UIViewController *)self.sourceViewController).view; UIView *dstView = ((UIViewController *)self.destinationViewController).view; [dstView setFrame:CGRectMake(0, 0, srcView.window.bounds.size.width, srcView.window.bounds.size.height)]; [srcView.window insertSubview:dstView belowSubview:srcView]; [UIView animateWithDuration:0.3 animations:^{ srcView.center = CGPointMake(srcView.center.x - srcView.frame.size.width, srcView.center.y); } completion:^(BOOL finished){ [srcView removeFromSuperview]; } ];
问题是目标 View 以纵向显示,即使应用中的所有其他 View 都是横向的。此外,x 和 y 坐标是相反的。为什么会这样?
我已经在每个 View Controller 中设置了 shouldAutorotateToInterfaceOrientation
,但这没有帮助。我可以使用 CGAffineTransformMakeRotation
旋转 View ,但这似乎不是正确的做法;一方面,坐标仍然会颠倒。
更新:
我尝试使用 CGAffineTransformRotate
来旋转 View ,但它看起来很荒谬。大多数背景显示为黑色。我认为这不是它应该的工作方式。
最佳答案
由于在 Controller 交换之前我无法获得目标 View 的正确方向和框架,所以我确实逆向了这个过程:
- 将源 View 保存为图像(参见 Remove custom UIStoryboardSegue with custom animation);
- 切换当前 Controller [presentViewController: ...];
- 然后,使用嵌入保存的源图像的(现在正确的)目标 View 制作动画。
完整代码如下:
#include <QuartzCore/QuartzCore.h>
@implementation HorizontalSwipingSegue
- (void) perform {
UIViewController *source = self.sourceViewController;
UIViewController *destination = self.destinationViewController;
UIView *sourceView = source.view;
UIView *destinationView = destination.view;
// Create a UIImageView with the contents of the source
UIGraphicsBeginImageContext(sourceView.bounds.size);
[sourceView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *sourceImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageView *sourceImageView = [[UIImageView alloc] initWithImage:sourceImage];
[[self sourceViewController] presentViewController:[self destinationViewController] animated:NO completion:NULL];
CGPoint destinationViewFinalCenter = CGPointMake(destinationView.center.x, destinationView.center.y);
CGFloat deltaX = destinationView.frame.size.width;
CGFloat deltaY = destinationView.frame.size.height;
switch (((UIViewController *)self.sourceViewController).interfaceOrientation) {
case UIDeviceOrientationPortrait:
destinationView.center = CGPointMake(destinationView.center.x - deltaX, destinationView.center.y);
sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaX, sourceImageView.center.y);
break;
case UIDeviceOrientationPortraitUpsideDown:
destinationView.center = CGPointMake(destinationView.center.x + deltaX, destinationView.center.y);
sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaX, sourceImageView.center.y);
break;
case UIDeviceOrientationLandscapeLeft:
destinationView.center = CGPointMake(destinationView.center.x, destinationView.center.y - deltaY);
sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaY, sourceImageView.center.y);
break;
case UIDeviceOrientationLandscapeRight:
destinationView.center = CGPointMake(destinationView.center.x, destinationView.center.y + deltaY);
sourceImageView.center = CGPointMake(sourceImageView.center.x + deltaY, sourceImageView.center.y);
break;
}
[destinationView addSubview:sourceImageView];
[UIView animateWithDuration:0.6f
animations:^{
destinationView.center = destinationViewFinalCenter;
}
completion:^(BOOL finished){
[sourceImageView removeFromSuperview];
}];
}
@end
关于objective-c - subview 方向错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11672306/