0

私はいくつかのレイヤーでビューを構成しており、そのうちのいくつかは回転しています。これらのレイヤーの表示は完全に機能しますが、画像を作成しようとすると、すべての回転/変換が無視されます。

たとえば、左を指す矢印のイメージを含む CALayer がある場合、(CATransform3DMakeRotation を使用して) z 軸を中心に回転した後、上を指し、レイヤーが正しく表示されます。ただし、(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
4

2 に答える 2

1

のドキュメントは次のように-[CALayer renderInContext:]述べています。

このメソッドのMacOSX v10.5実装は、CoreAnimationコンポジションモデル全体をサポートしていません。QCCompositionLayer、CAOpenGLLayer、およびQTMovieLayerレイヤーはレンダリングされません。さらに、3D変換を使用するレイヤーはレンダリングされず、backgroundFilters、filters、compositingFilter、またはマスク値を指定するレイヤーもレンダリングされません。Mac OS Xの将来のバージョンでは、これらのレイヤーとプロパティのレンダリングのサポートが追加される可能性があります。

(この制限はiOSにも存在します。)

ヘッダーCALayer.hには次のようにも書かれています。

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

基本的に-renderInContext:、いくつかの単純なケースで役立ちますが、より複雑な状況では期待どおりに機能しません。あなたはあなたの絵を描くために他の方法を見つける必要があるでしょう。Quartz(Core Graphics)は2Dで機能しますが、3Dでは自分で操作できます。

于 2012-07-24T17:56:27.950 に答える
0

CATransform3DMakeRotation の代わりに Core Graphic を使用できます :)

CGAffineTransform flip = CGAffineTransformMakeScale(1.0, -1.0);
于 2015-10-29T05:22:26.480 に答える