Попытка сделать карту из CALayers, которая может перевернуть - PullRequest
8 голосов
/ 30 сентября 2010

Я пытался разработать основанный на CALayer объект "CardView", который имеет два слоя, которые обращены друг к другу, чтобы представить две стороны карты.Я работал с такими вещами, как doublesided свойство CALayer, и нахожу результаты смущающими.Мой базовый класс - CALayer, и я добавляю к нему два sublayers, один с преобразованием M_PI / 2 и оба с doublesided = NO, но когда он стоит, я получаю фронт, показывающий, как бы я ни поворачивал карту испина не показывает вообще.Если я не создаю лицевую сторону, задняя сторона отображается через обе стороны, и текст находится в одном углу, а не в 48 точках и размыт.

Вот ссылка на скриншот, показывающий, что карта только что завершила полный оборот вUIViewController's вид.Вы видите заднюю часть фронта.Это должно быть невидимым, и задняя часть должна показывать ... Я думаю ...

https://files.me.com/gazelips/lj2aqo


//  CardView.h

#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>

#define kCardWidth 100.0f
#define kCardHeight 150.0f

@interface CardView : CALayer {
    CALayer *cardFront, *cardBack;
}

@property (nonatomic, retain) CALayer *cardFront, *cardBack;

- (id)initWithPosition:(CGPoint)point;
- (void)addPerspective;
- (CALayer *)createFront;
- (CALayer *)createBack;

@end

//  CardView.m

#import "CardView.h"

@implementation CardView

@synthesize cardFront, cardBack;

static CATransform3D kPerspectiveTransform;

- (id)initWithPosition:(CGPoint)point {
    NSLog(@"--initWithPosition:CardView");
    self = [super init];
    if (self != nil) {
        [self addPerspective];
        self.bounds = CGRectMake(0, 0, kCardWidth, kCardHeight);
        self.position = point;
        self.edgeAntialiasingMask = 0;
        self.backgroundColor = [[UIColor clearColor] CGColor];
        self.borderColor = [[UIColor blackColor] CGColor];
        self.borderWidth = 0.5;
        self.doubleSided = YES;

        cardBack = [self createBack];
        [self addSublayer: cardBack];

        cardFront = [self createFront];
        [self addSublayer: cardFront];
    }
    return self;
}

- (void)addPerspective {
    NSLog(@"--prepare:CardView");
    kPerspectiveTransform = CATransform3DIdentity;
    kPerspectiveTransform.m34 = -1.0/800.0;
    self.transform = kPerspectiveTransform;
}   

- (CALayer *)createFront {
    NSLog(@"--createFront:CardView");
    CALayer *front = [[CALayer alloc] init];
    front.bounds = CGRectMake(0.0f, 0.0f, kCardWidth, kCardHeight);
    front.position = CGPointMake(kCardWidth / 2, kCardHeight / 2);
    front.edgeAntialiasingMask = 0;
    front.backgroundColor = [[UIColor whiteColor] CGColor];
    front.cornerRadius = 8 * (kCardHeight/150);
    front.borderWidth = 1;
    front.borderColor = [[UIColor grayColor] CGColor];
    front.doubleSided = NO;

    return [front autorelease];
}

- (CALayer *)createBack {
    NSLog(@"--createBack:CardView");
    CALayer *back = [[CALayer alloc] init];
    back.bounds = CGRectMake(0.0f, 0.0f, kCardWidth, kCardHeight);
    back.position = CGPointMake(kCardWidth / 2, kCardHeight / 2);
    back.backgroundColor = [[UIColor blueColor] CGColor];
    back.contentsGravity = kCAGravityResize;
    back.masksToBounds = YES;
    back.borderWidth = 4 * (kCardHeight/150);
    back.borderColor = [[UIColor grayColor] CGColor];;
    back.cornerRadius = 8 * (kCardHeight/150);
    back.edgeAntialiasingMask = 0;
    back.doubleSided = NO;

    CATextLayer *textLayer = [CATextLayer layer];
    textLayer.font = [UIFont boldSystemFontOfSize:48];
    textLayer.bounds = CGRectMake(0.0f, 0.0f, kCardWidth, kCardHeight);
    textLayer.position = CGPointMake(50.0f, 75.0f);
    textLayer.string = @"Steve";
    [back addSublayer:textLayer];

    back.transform = CATransform3DMakeRotation(M_PI, 0.0f, 1.0f, 0.0f);
    return [back autorelease];
}

@end

Ответы [ 3 ]

23 голосов
/ 06 октября 2010

Трюк в конечном итоге заключался в использовании CATransformLayer. Этот слой предназначен только для хранения других слоев (он не может иметь такие вещи, как backgroundColor или borderWidth).Однако он поддерживает истинные трехмерные отношения своих дочерних слоев (то есть не выравнивает их как обычный CALayer).Таким образом, вы можете сделать два слоя, перевернуть один и сместить его zPosition просто на волосы и поместить их оба в CATransformLayer, и теперь вы можете перевернуть этот родительский слой шестью способами с воскресенья, а дочерние слои останутся заблокированными и всегда будут правильно отображаться,Довольно мило и низко над головой!

1 голос
/ 30 сентября 2010

Существует гораздо более простой способ сделать это, если вы только пытаетесь сделать нормальный «переворот».

Посмотрите на систему анимации UIView, и там есть «transitionWithView».Вы можете применить там анимацию кувырка, и она даст тот же эффект, почти без работы.

0 голосов
/ 29 декабря 2011

Я также прочитал многие версии для UIView. После того, как они сложили все вместе, вот что я получил, и это работает.

Для настройки я установил

1) карта в построителе интерфейса с объектом представления, который содержит объект UIImageView, который показывает лицевую сторону карты. так View-> View-> UIImageView-> файл изображения лицевой стороны карты

2) Затем объект View, содержащий UIImageView, изменяется на класс UIController (чтобы он реагировал на прикосновения).

3) В заголовочном файле viewcontroller я создал IBOutlet UIImageView cardView, связанный с UIImageView, и IBAction flipCard, связанный с объектом View (который теперь является объектом UIController) через событие «touch down»。

4) IBAction flipCard реализуется путем динамического создания другого объекта View подпредставления, содержащего другой UIImageView, но init с изображением задней стороны.

5) с помощью CGRect рамка и центр объекта на задней стороне выровнены с лицевой стороной.

6) затем вызываются методы анимации UIView для замены подвидов анимацией.

И это делает трюк.

Я сейчас не на своем Mac, поэтому у меня нет кодов. Если кому-то интересно, могу выложить позже.

...