2012-07-24 34 views
0

我正在用几个图层组成一个视图,其中一些图层被旋转。这些图层的显示效果很好,但是当我尝试制作图像时,所有旋转/转换都会被忽略。旋转图层的图形上下文忽略任何转换

例如,如果我有一个CALayer,它包含一个箭头指向左侧的图像,围绕z轴旋转后(使用CATransform3DMakeRotation)它指向顶部,并且图层被正确显示。但是,如果我得到此图层的图像(使用renderInContext),箭头仍然指向左侧,忽略任何转换。

任何人都知道为什么,我该怎么做才能得到我想要的结果? :-)

示例代码:

// ViewController.m 

#import "ViewController.h" 
#import <QuartzCore/QuartzCore.h> 

// Don't forget to add the QuartzCore framework to your target. 

@interface ViewController() 
@end 

@implementation ViewController 

- (void)loadView { 
    self.view = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.view.backgroundColor = [UIColor lightGrayColor]; 
} 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    // Get the arrow image (tip to the left, 50 x 50 pixels). 
    // (Download the image from here: http://www.4shared.com/photo/uQfor7vC/arrow.html) 
    UIImage *arrowImage = [UIImage imageNamed:@"arrow"]; 

    // The arrow layer in it's starting orientation (tip to the left). 
    CGRect layerFrame = CGRectMake(50.0, 50.0, arrowImage.size.width, arrowImage.size.height); 
    CALayer *arrowLayerStart = [CALayer new]; 
    arrowLayerStart.frame = layerFrame; 
    [arrowLayerStart setContents:(id)[arrowImage CGImage]]; 
    [self.view.layer addSublayer:arrowLayerStart]; 

    // The arrow layer rotated around the z axis by 90 degrees. 
    layerFrame.origin = CGPointMake(layerFrame.origin.x + layerFrame.size.width + 25.0, layerFrame.origin.y); 
    CALayer *arrowLayerZ90 = [CALayer new]; 
    arrowLayerZ90.frame = layerFrame; 
    [arrowLayerZ90 setContents:(id)[arrowImage CGImage]]; 
    arrowLayerZ90.transform = CATransform3DMakeRotation(M_PI/2.0, 0.0, 0.0, 1.0); 
    [self.view.layer addSublayer:arrowLayerZ90]; 

    // Now make images of each of these layers and display them in a second row. 

    // The starting layer without any rotation. 
    UIGraphicsBeginImageContext(arrowLayerStart.frame.size); 
    [arrowLayerStart renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *arrowStartImage = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    layerFrame.origin = CGPointMake(arrowLayerStart.frame.origin.x, 
            arrowLayerStart.frame.origin.y + arrowLayerStart.frame.size.height + 25.0); 
    CALayer *arrowLayerStartCaptured = [CALayer new]; 
    arrowLayerStartCaptured.frame = layerFrame; 
    [arrowLayerStartCaptured setContents:(id)[arrowStartImage CGImage]]; 
    [self.view.layer addSublayer:arrowLayerStartCaptured]; 

    // The second layer, rotated around the z axis by 90 degrees. 
    UIGraphicsBeginImageContext(arrowLayerZ90.frame.size); 
    [arrowLayerZ90 renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *arrowZ90Image = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    layerFrame.origin = CGPointMake(arrowLayerZ90.frame.origin.x, 
            arrowLayerZ90.frame.origin.y + arrowLayerZ90.frame.size.height + 25.0); 
    CALayer *arrowLayerZ90Captured = [CALayer new]; 
    arrowLayerZ90Captured.frame = layerFrame; 
    [arrowLayerZ90Captured setContents:(id)[arrowZ90Image CGImage]]; 
    [self.view.layer addSublayer:arrowLayerZ90Captured];  
} 

@end 


// ViewController.h 

#import <UIKit/UIKit.h> 

@interface ViewController : UIViewController 
@end 


// AppDelegate.h 

#import <UIKit/UIKit.h> 

@interface AppDelegate : UIResponder <UIApplicationDelegate> 
@property (strong, nonatomic) UIWindow *window; 
@end 


// AppDelegate.m 

#import "AppDelegate.h" 
#import "ViewController.h" 

@implementation AppDelegate 
@synthesize window = _window; 

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 
    self.window.rootViewController = [[ViewController alloc] init]; 
    [self.window makeKeyAndVisible]; 
    return YES; 
} 

@end 

回答

1

The documentation for -[CALayer renderInContext:]说:

Mac OS X的V10.5此方法的实现并不 支持整个核心动画组合模型。 QCCompositionLayer,CAOpenGLLayer和QTMovieLayer图层不是 呈现。此外,使用3D变换的图层不是 呈现的,也不是指定backgroundFilters,过滤器, compositingFilter或掩码值的图层。未来版本的Mac OS X可能支持 渲染这些图层和属性。

(这种局限性是在iOS上,太)

CALayer.h还说:

* WARNING: currently this method does not implement the full 
* CoreAnimation composition model, use with caution. */ 

从本质上讲,-renderInContext:是在一些简单的情况下非常有用,但将无法正常工作预计在更复杂的情况下。您需要找到其他方式来完成您的绘图。石英(核心图形)将适用于2D,但对于3D,则是您自己。

+0

非常感谢。我会看到做一个解决方法。事实上,我并不需要任何3D旋转,所以我会看到我能用2D做些什么。 – 2012-07-25 21:14:43

0

您可以使用核心Graphaic代替CATransform3DMakeRotation的:)

CGAffineTransform flip = CGAffineTransformMakeScale(1.0, -1.0);