NSView not rotating around center - nsview

I'm trying to rotate a NSView around its center. But even if I change the anchorPoint, the NSView continue to rotate around its top left corner. Just a precision : I'm working on OSX 10.8.5.
Thanks in advance for your help.
Here is my code :
// myView.m
- (id)initWithFrame:(NSRect)rect
{
if(self = [super initWithFrame:(NSRect)rect])
{
self.frame = rect;
[self setWantsLayer:YES];
self.layer.backgroundColor = [NSColor whiteColor].CGColor;
self.layer.borderColor = [NSColor grayColor].CGColor;
self.layer.borderWidth = 1.0;
NSView *aView = [[NSView alloc] initWithFrame:NSMakeRect(0, 0, 50, 50)];
[aView setWantsLayer:YES];
aView.layer.backgroundColor = [NSColor redColor].CGColor;
aView.layer.anchorPoint = CGPointMake(0.5, 0.5);
[self addSubview:aView];
CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
rotateAnimation.byValue = [NSNumber numberWithFloat:2*M_PI];
rotateAnimation.duration = 4;
rotateAnimation.repeatCount = INFINITY;
[aView.layer addAnimation:rotateAnimation forKey:#"rotationAnimation"];
}
}
EDITED 30-11-2018 : I managed to get the centered rotation using the layers :
// myView.m
- (id)initWithFrame:(NSRect)rect
{
if(self = [super initWithFrame:(NSRect)rect])
{
self.frame = rect;
[self setWantsLayer:YES];
self.layer.backgroundColor = [NSColor whiteColor].CGColor;
self.layer.borderColor = [NSColor grayColor].CGColor;
self.layer.borderWidth = 1.0;
NSView *aView = [[NSView alloc] init];
[aView setWantsLayer:YES];
aView.layer.backgroundColor = [NSColor redColor].CGColor;
aView.layer.bounds = CGRectMake(0, 0, 50, 50);
aView.layer.frame = CGRectMake(0, 0, 50, 50);
aView.layer.anchorPoint = CGPointMake(0.5, 0.5);
aView.layer.position = CGPointMake(0, 0);
[self.layer addSublayer:aView.layer];
CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
rotateAnimation.byValue = [NSNumber numberWithFloat:2*M_PI];
rotateAnimation.duration = 4;
rotateAnimation.repeatCount = INFINITY;
[aView.layer addAnimation:rotateAnimation forKey:#"rotationAnimation"];
}
}

If you want to rotate a view you can do:
-(void)rotateByCenter:(NSView*)aView {
[aView setWantsLayer:YES];
aView.layer.anchorPoint = CGPointMake(0.5, 0.5);
aView.layer.position = CGPointMake(aView.frame.origin.x + aView.frame.size.width/2.,aView.frame.origin.y + aView.frame.size.height/2.) ;
CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
rotateAnimation.byValue = [NSNumber numberWithFloat:2*M_PI];
rotateAnimation.duration = 20;
rotateAnimation.repeatCount = INFINITY;
[aView.layer addAnimation:rotateAnimation forKey:#"rotationAnimation"]; }

Related

CAShapeLayer LineCap not proper at end of CABasic Animation

I have implemented a basic line drawing animation for a progress bar.The line has a round cap edge.When I animated the line drawing the beginning of line is having a rounded cap but in the end its a square. below is the code I am using am i missing anything??
CAShape Layer Code :
CAShapeLayer *lineLayer = [[CAShapeLayer alloc] init];
[lineLayer setFrame: CGRectMake(0,
0,
wifisyncView.popUpView.frame.size.width,
wifisyncView.popUpView.frame.size.height)];
[lineLayer setPath: [linePath CGPath]];
lineLayer.lineWidth = 9.0f;
lineLayer.strokeEnd = 9.0f;
lineLayer.fillColor = [[UIColor orangeColor] CGColor];
lineLayer.lineCap = kCALineCapRound;
[lineLayer setStrokeColor:[[UIColor orangeColor] CGColor]];
[lineLayer setMasksToBounds:YES];
lineLayer.cornerRadius = 30.0f;
CABASIC Animation code :
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
drawAnimation.duration = 5.0; // "animate over 5 seconds "
drawAnimation.repeatCount = 1.0; // Animate only once..
drawAnimation.removedOnCompletion = NO;// Remain stroked after the animation..
drawAnimation.fillMode = kCAFillModeForwards;
// Animate from no part of the stroke being drawn to the entire stroke being drawn
drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
drawAnimation.toValue = [NSNumber numberWithFloat:1.0f];
// Experiment with timing to get the appearence to look the way you want
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
drawAnimation.delegate = self;
// Add the animation to the circle
[lineLayer addAnimation:drawAnimation forKey:#"drawLineAnimation"];
Image Attached :
I dont find any mistakes in your code. I created a new project and pasted your code to viewDidLoad and is working fine. Code for your reference.
UIBezierPath *linePath = [UIBezierPath bezierPath];
[linePath moveToPoint:CGPointMake(100, 100)];
[linePath addLineToPoint:CGPointMake(500, 100)];
CAShapeLayer *lineLayer = [[CAShapeLayer alloc] init];
[lineLayer setFrame:self.view.bounds];
[lineLayer setPath: [linePath CGPath]];
lineLayer.lineWidth = 9.0f;
lineLayer.strokeEnd = 9.0f;
lineLayer.fillColor = [[UIColor orangeColor] CGColor];
lineLayer.lineCap = kCALineCapRound;
[lineLayer setStrokeColor:[[UIColor orangeColor] CGColor]];
[lineLayer setMasksToBounds:YES];
lineLayer.cornerRadius = 30.0f;
[self.view.layer addSublayer:lineLayer];
CABasicAnimation *drawAnimation = [CABasicAnimation animationWithKeyPath:#"strokeEnd"];
drawAnimation.duration = 5.0; // "animate over 5 seconds "
drawAnimation.repeatCount = 1.0; // Animate only once..
drawAnimation.removedOnCompletion = NO;// Remain stroked after the animation..
drawAnimation.fillMode = kCAFillModeForwards;
// Animate from no part of the stroke being drawn to the entire stroke being drawn
drawAnimation.fromValue = [NSNumber numberWithFloat:0.0f];
drawAnimation.toValue = [NSNumber numberWithFloat:1.0f];
// Experiment with timing to get the appearence to look the way you want
drawAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
drawAnimation.delegate = self;
// Add the animation to the circle
[lineLayer addAnimation:drawAnimation forKey:#"drawLineAnimation"];
I think you should try changing
[lineLayer setFrame: CGRectMake(0,
0,
wifisyncView.popUpView.frame.size.width,
wifisyncView.popUpView.frame.size.height)];
to
[lineLayer setFrame: CGRectMake(0,
0,
wifisyncView.popUpView.bounds.size.width,
wifisyncView.popUpView.bounds.size.height)];

Iphone-How do I get an image to rotate continously for about 60 seconds and then stop in the other direction

I need the image to spin around a few times and come to a stop in the opposite dirrection. THe image is a button with arrow that points right and then it spins a few times and comes to a stop facing the other way. Any help will be appreciated.
This is what I have at the moment.
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.duration = 0.60;//animation.duration = 0.60;
animation.repeatCount = 1;//animation.repeatCount = 1000ˆ
//#warning remove comment brackets below
animation.keyTimes = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:1.0], nil];
animation.values = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:(degrees / 180)*M_PI], nil];
animation.fillMode = kCAFillModeForwards;
Please try this and let me know. This is working for me.
UIImageView *tempView = [[UIImageView alloc] initWithFrame:CGRectMake(100, 100, 80, 80)];
tempView.image = [UIImage imageNamed:#"Icon"];
tempView.backgroundColor = [UIColor redColor];
[self.view addSubview:tempView];
const NSUInteger rotations = 10;
const NSTimeInterval duration = 5;
CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:#"transform.rotation"];
CGFloat touchUpStartAngle = 0;
CGFloat touchUpEndAngle = (M_PI);
CGFloat angularVelocity = (((2 * M_PI) * rotations) + M_PI) / duration;
anim.values = #[#(touchUpStartAngle), #(touchUpStartAngle + angularVelocity * duration)];
anim.duration = duration;
anim.autoreverses = NO;
anim.delegate = self;
anim.repeatCount = 1;
anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
[tempView.layer addAnimation:anim forKey:#"test"];
tempView.transform = CGAffineTransformMakeRotation(touchUpStartAngle + (touchUpEndAngle));
The following code works for me. It actually doesn´t change the direction. I think you can achieve this by adding a timer which change the imagesArray.
First I also tried using CAKeyframeAnimation like you but I couldn´t figure it out. So I changed to an animating image - I thought this way couldn´t be too bad, because Apple e.g. use this way also for animating the activity indicator.
-(void) myImageInitFunction {
UIImage *icon = [UIImage imageNamed:#"yourIconImage"];
NSArray *imagesArray = rotatingImagesArrayOfImage(icon, 30);
myImageViewThatShouldRotate.animationImages = imageArray;
myImageViewThatShouldRotate.animationDuration= 2.0;
[myImageViewThatShouldRotate startAnimating];
}
NSArray *rotatingImagesArrayOfImage(UIImage * icon, NSInteger nFrames)
{
NSMutableArray *images = [NSMutableArray arrayWithObject:icon];
for (NSInteger nLoop = 1; nLoop < nFrames; nLoop++) {
[images addObject: [UIImage imageWithCGImage: CGImageRotatedByAngle(icon.CGImage, nLoop * ( 360 / nFrames)) ] ];
}
return images;
}
CGImageRef CGImageRotatedByAngle(CGImageRef imgRef, CGFloat angle) {
CGFloat angleInRadians = angle * (M_PI / 180);
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGRect imgRect = CGRectMake(0, 0, width, height);
CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bmContext = CGBitmapContextCreate(NULL,
rotatedRect.size.width,
rotatedRect.size.height,
8,
0,
colorSpace,
kCGImageAlphaPremultipliedFirst);
CGContextSetAllowsAntialiasing(bmContext, YES);
CGContextSetShouldAntialias(bmContext, YES);
CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh);
CGColorSpaceRelease(colorSpace);
CGContextTranslateCTM(bmContext,
+(rotatedRect.size.width/2),
+(rotatedRect.size.height/2));
CGContextRotateCTM(bmContext, angleInRadians);
CGContextTranslateCTM(bmContext,
-(rotatedRect.size.width/2),
-(rotatedRect.size.height/2));
CGContextDrawImage(bmContext, CGRectMake(0, 0,
rotatedRect.size.width,
rotatedRect.size.height),
imgRef);
CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
CFRelease(bmContext);
return rotatedImage;
}
i use this:
- (void)startAnimations {
CABasicAnimation* spinAnimation = [CABasicAnimation
animationWithKeyPath:#"transform.rotation"];
spinAnimation.toValue = [NSNumber numberWithFloat:M_PI];
spinAnimation.cumulative = YES;
spinAnimation.duration = 0.5;
spinAnimation.repeatCount = 10000;
[imageView.layer addAnimation:spinAnimation forKey:#"spinAnimation"];
}
- (void)cancelAnimations {
[imageView.layer removeAnimationForKey:#"spinAnimation"];
imageView.transform = CGAffineTransformMakeRotation(0.0);
}
call a timer in start animations to call cancelanimations in 60 secs. you can make rotation angle whatever you want
Thanks everyone this page is now very resourceful.
This is another solution.
- (CAKeyframeAnimation *)rotateFrom:(CGFloat)fromDegrees to:(CGFloat)toDegrees {
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:#"transform.rotation.z"];
animation.delegate = self;
animation.duration = 0.30;
animation.repeatCount = 1;
animation.keyTimes = [NSArray arrayWithObjects:
[NSNumber numberWithFloat:0.0],
[NSNumber numberWithFloat:1.0], nil];
animation.values= [NSArray arrayWithObjects:
[NSNumber numberWithFloat:fromDegrees*(M_PI/180)],
[NSNumber numberWithFloat:toDegrees*(M_PI/180)], nil];
animation.fillMode = kCAFillModeForwards;
animation.removedOnCompletion = NO;
return animation;
}

iOS Paper fold (origami / accordion) effect animation, with manual control

I'm looking for tips on how to implement the popular 'paper folding / origami' effect in my iOS project.
I'm aware of projects such as:
https://github.com/xyfeng/XYOrigami
but they only offer the 'animated' effect, with no manual control over the opening animation.
I've struggled to dissect that project and come up with what I'm after.
To be more exact, I'm looking on how to implement the effect shown here: http://vimeo.com/41495357 where the folding animation is not simply animated open, but the user controls the opening folds.
Any help would be much appreciated, thanks in advance!
EDIT:
Okay, here's some example code to better illustrate what I'm struggling with:
This method triggers the origami effect animation:
- (void)showOrigamiTransitionWith:(UIView *)view
NumberOfFolds:(NSInteger)folds
Duration:(CGFloat)duration
Direction:(XYOrigamiDirection)direction
completion:(void (^)(BOOL finished))completion
{
if (XY_Origami_Current_State != XYOrigamiTransitionStateIdle) {
return;
}
XY_Origami_Current_State = XYOrigamiTransitionStateUpdate;
//add view as parent subview
if (![view superview]) {
[[self superview] insertSubview:view belowSubview:self];
}
//set frame
CGRect selfFrame = self.frame;
CGPoint anchorPoint;
if (direction == XYOrigamiDirectionFromRight) {
selfFrame.origin.x = self.frame.origin.x - view.bounds.size.width;
view.frame = CGRectMake(self.frame.origin.x+self.frame.size.width-view.frame.size.width, self.frame.origin.y, view.frame.size.width, view.frame.size.height);
anchorPoint = CGPointMake(1, 0.5);
}
else {
selfFrame.origin.x = self.frame.origin.x + view.bounds.size.width;
view.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, view.frame.size.width, view.frame.size.height);
anchorPoint = CGPointMake(0, 0.5);
}
UIGraphicsBeginImageContext(view.frame.size);
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewSnapShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//set 3D depth
CATransform3D transform = CATransform3DIdentity;
transform.m34 = -1.0/800.0;
CALayer *origamiLayer = [CALayer layer];
origamiLayer.frame = view.bounds;
origamiLayer.backgroundColor = [UIColor colorWithWhite:0.2 alpha:1].CGColor;
origamiLayer.sublayerTransform = transform;
[view.layer addSublayer:origamiLayer];
//setup rotation angle
double startAngle;
CGFloat frameWidth = view.bounds.size.width;
CGFloat frameHeight = view.bounds.size.height;
CGFloat foldWidth = frameWidth/(folds*2);
CALayer *prevLayer = origamiLayer;
for (int b=0; b < folds*2; b++) {
CGRect imageFrame;
if (direction == XYOrigamiDirectionFromRight) {
if(b == 0)
startAngle = -M_PI_2;
else {
if (b%2)
startAngle = M_PI;
else
startAngle = -M_PI;
}
imageFrame = CGRectMake(frameWidth-(b+1)*foldWidth, 0, foldWidth, frameHeight);
}
else {
if(b == 0)
startAngle = M_PI_2;
else {
if (b%2)
startAngle = -M_PI;
else
startAngle = M_PI;
}
imageFrame = CGRectMake(b*foldWidth, 0, foldWidth, frameHeight);
}
CATransformLayer *transLayer = [self transformLayerFromImage:viewSnapShot Frame:imageFrame Duration:duration AnchorPiont:anchorPoint StartAngle:startAngle EndAngle:0];
[prevLayer addSublayer:transLayer];
prevLayer = transLayer;
}
[CATransaction begin];
[CATransaction setCompletionBlock:^{
self.frame = selfFrame;
[origamiLayer removeFromSuperlayer];
XY_Origami_Current_State = XYOrigamiTransitionStateShow;
if (completion)
completion(YES);
}];
[CATransaction setValue:[NSNumber numberWithFloat:duration] forKey:kCATransactionAnimationDuration];
CAAnimation *openAnimation = [CAKeyframeAnimation animationWithKeyPath:#"position.x" function:openFunction fromValue:self.frame.origin.x+self.frame.size.width/2 toValue:selfFrame.origin.x+self.frame.size.width/2];
openAnimation.fillMode = kCAFillModeForwards;
[openAnimation setRemovedOnCompletion:NO];
[self.layer addAnimation:openAnimation forKey:#"position"];
[CATransaction commit];
}
The method grabs a CATransform Layer from this method:
- (CATransformLayer *)transformLayerFromImage:(UIImage *)image Frame:(CGRect)frame Duration:(CGFloat)duration AnchorPiont:(CGPoint)anchorPoint StartAngle:(double)start EndAngle:(double)end;
{
CATransformLayer *jointLayer = [CATransformLayer layer];
jointLayer.anchorPoint = anchorPoint;
CGFloat layerWidth;
if (anchorPoint.x == 0) //from left to right
{
layerWidth = image.size.width - frame.origin.x;
jointLayer.frame = CGRectMake(0, 0, layerWidth, frame.size.height);
if (frame.origin.x) {
jointLayer.position = CGPointMake(frame.size.width, frame.size.height/2);
}
else {
jointLayer.position = CGPointMake(0, frame.size.height/2);
}
}
else
{ //from right to left
layerWidth = frame.origin.x + frame.size.width;
jointLayer.frame = CGRectMake(0, 0, layerWidth, frame.size.height);
jointLayer.position = CGPointMake(layerWidth, frame.size.height/2);
}
//map image onto transform layer
CALayer *imageLayer = [CALayer layer];
imageLayer.frame = CGRectMake(0, 0, frame.size.width, frame.size.height);
imageLayer.anchorPoint = anchorPoint;
imageLayer.position = CGPointMake(layerWidth*anchorPoint.x, frame.size.height/2);
[jointLayer addSublayer:imageLayer];
CGImageRef imageCrop = CGImageCreateWithImageInRect(image.CGImage, frame);
imageLayer.contents = (__bridge id)imageCrop;
imageLayer.backgroundColor = [UIColor clearColor].CGColor;
//add shadow
NSInteger index = frame.origin.x/frame.size.width;
double shadowAniOpacity;
CAGradientLayer *shadowLayer = [CAGradientLayer layer];
shadowLayer.frame = imageLayer.bounds;
shadowLayer.backgroundColor = [UIColor darkGrayColor].CGColor;
shadowLayer.opacity = 0.0;
shadowLayer.colors = [NSArray arrayWithObjects:(id)[UIColor blackColor].CGColor, (id)[UIColor clearColor].CGColor, nil];
if (index%2) {
shadowLayer.startPoint = CGPointMake(0, 0.5);
shadowLayer.endPoint = CGPointMake(1, 0.5);
shadowAniOpacity = (anchorPoint.x)?0.24:0.32;
}
else {
shadowLayer.startPoint = CGPointMake(1, 0.5);
shadowLayer.endPoint = CGPointMake(0, 0.5);
shadowAniOpacity = (anchorPoint.x)?0.32:0.24;
}
[imageLayer addSublayer:shadowLayer];
//animate open/close animation
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.y"];
[animation setDuration:duration];
[animation setFromValue:[NSNumber numberWithDouble:start]];
[animation setToValue:[NSNumber numberWithDouble:end]];
[animation setRemovedOnCompletion:NO];
[jointLayer addAnimation:animation forKey:#"jointAnimation"];
//animate shadow opacity
animation = [CABasicAnimation animationWithKeyPath:#"opacity"];
[animation setDuration:duration];
[animation setFromValue:[NSNumber numberWithDouble:(start)?shadowAniOpacity:0]];
[animation setToValue:[NSNumber numberWithDouble:(start)?0:shadowAniOpacity]];
[animation setRemovedOnCompletion:NO];
[shadowLayer addAnimation:animation forKey:nil];
return jointLayer;
}
Basically, I need to remove the automatic animation, and control the progress of the effect using some manually set value (e.g.: uislider value, or content offset).
Once again, any help provided is much appreciated!
I write another library for folding transition : https://github.com/geraldhuard/YFoldView
Hope it works for you.
Try this. You have drag control over the paper fold, left and right side.
https://github.com/honcheng/PaperFold-for-iOS
This is the best solution I've seen:
http://api.mutado.com/mobile/paperstack/
EDIT: What about this: the paper folding/unfolding effect in twitter for iPad

Why are CALayers stacking ontop of each other as I scroll my UITableView?

I have a UITableViewCell with a UIImage that I'm drawing. As I scroll, I get a ton of sublayers getting added which makes performance really jerky. How can I make sure my CALayer only gets added once?
- (void) drawContentView:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
[[UIColor whiteColor] set];
CGContextFillRect(context, rect);
NSString* caption = [NSString stringWithFormat:#"%#",[info objectForKey:#"caption"]];
NSString* text = [info stringForKey:#"text"];
CGFloat widthr = self.frame.size.width - 70;
[[UIColor grayColor] set];
[text drawInRect:CGRectMake(63.0, 25.0, widthr, 20.0) withFont:system14 lineBreakMode:UILineBreakModeTailTruncation];
if (self.image) {
UIImage *imageToDisplay;
imageToDisplay = self.image;
imageToDisplay = [self imageWithImage:imageToDisplay scaledToSize:CGSizeMake(imageToDisplay.size.width / 1.5, imageToDisplay.size.height / 1.5)];
CGFloat width;
CGFloat height;
CGRect r;
if (imageToDisplay.size.width < 310 && imageToDisplay.size.height > 290) {
imageToDisplay = [self imageByCropping:imageToDisplay toRect:CGRectMake(0, 20, imageToDisplay.size.width, 270)];
}
else if (imageToDisplay.size.width > 310 && imageToDisplay.size.height < 20) {
imageToDisplay = [self imageByCropping:imageToDisplay toRect:CGRectMake(30, 0, 290, imageToDisplay.size.height)];
}
else {
if (![caption isEqualToString:#""]) {
imageToDisplay = [self imageByCropping:imageToDisplay toRect:CGRectMake(30, 0, 290, 230)];
}
else {
imageToDisplay = [self imageByCropping:imageToDisplay toRect:CGRectMake(30, 0, 290, 270)];
}
}
width = imageToDisplay.size.width;
height = imageToDisplay.size.height;
r = CGRectMake(5.0, 5.0, width, height);
//[imageToDisplay drawInRect:r];
CALayer *sublayer = [CALayer layer];
sublayer.contents = (id)imageToDisplay.CGImage;
sublayer.shadowOffset = CGSizeMake(0, 3);
sublayer.shadowRadius = 5.0;
sublayer.shadowColor = [UIColor blackColor].CGColor;
sublayer.shadowOpacity = 0.8;
sublayer.frame = CGRectMake(5.0, 5.0, imageToDisplay.size.width, imageToDisplay.size.height);
[self.layer addSublayer:sublayer];
//Experimental shadow stuff with images
/*CALayer *layer = [CALayer layer];
layer = [CALayer layer];
layer.bounds = CGRectMake(5.0, 5.0, imageToDisplay.size.width, imageToDisplay.size.height);
layer.position = CGPointMake(150, 140);
layer.contents = (id)imageToDisplay.CGImage;
layer.shadowOffset = CGSizeMake(0, 2);
layer.shadowOpacity = 0.70;
[self.layer addSublayer:layer];
[self bezierPathWithCurvedShadowForRect:layer.bounds];*/
[[UIColor blackColor] set];
[caption drawInRect:CGRectMake(10.0, height + 20 , widthr, 20.0) withFont:system14 lineBreakMode:UILineBreakModeWordWrap alignment:UITextAlignmentCenter];
}
}
drawContentView: is not the right method from which to call addSublayer:. You should add that layer at the point when you construct your object with an image, or when you set an image on an existing object. Alternatively, you can draw the image yourself in the drawContentView:, but it is probably not going to be as fast.

iPhone UIImageView and CABasicAnimation

I am doing a simple card rotation which works fine, but when I add a custom image background, after the card roation, the image is half chopped off. Any ideas?
float scaleValue = M_PI/2;
CABasicAnimation *yRotation;
yRotation = [CABasicAnimation animationWithKeyPath:#"transform.rotation.y"];
yRotation.fromValue = [NSNumber numberWithFloat:0.0];
yRotation.toValue = [NSNumber numberWithFloat:scaleValue];
yRotation.duration = .5;
CABasicAnimation *yRotation2;
yRotation2 = [CABasicAnimation animationWithKeyPath:#"transform.rotation.y"];
yRotation2.fromValue = [NSNumber numberWithFloat:scaleValue];
yRotation2.toValue = [NSNumber numberWithFloat:0.0];
yRotation2.duration = .5;
yRotation2.cumulative = YES;
yRotation2.beginTime = .5;
CAAnimationGroup *groupAnim = [CAAnimationGroup animation];
groupAnim.removedOnCompletion = NO;
groupAnim.duration = 1;
groupAnim.fillMode = kCAFillModeForwards;
groupAnim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
groupAnim.animations = [NSArray arrayWithObjects:yRotation, yRotation2, nil];
[[image objectAtIndex:num] addAnimation:groupAnim forKey:#"animateCard"];
[self.view bringSubviewToFront:[image objectAtIndex:num]];
This code is help to you .......
once try it will be perfectly working...without choppedoff
- (void)loadView {
[super loadView];
self.view.backgroundColor = [UIColor blackColor];
// Orbit #1
CALayer *orbit1 = [CALayer layer];
orbit1.bounds = CGRectMake(0, 0, 200, 200);
orbit1.position = self.view.center;
orbit1.cornerRadius = 100;
orbit1.borderColor = [UIColor redColor].CGColor;
orbit1.borderWidth = 1.5;
CALayer *planet1 = [CALayer layer];
planet1.bounds = CGRectMake(0, 0, 20, 20);
planet1.position = CGPointMake(100, 0);
planet1.cornerRadius = 10;
planet1.backgroundColor = [UIColor redColor].CGColor;
[orbit1 addSublayer:planet1];
CABasicAnimation *anim1 = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
anim1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
anim1.fromValue = [NSNumber numberWithFloat:0];
anim1.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
anim1.repeatCount = HUGE_VALF;
anim1.duration = 8.0;
[orbit1 addAnimation:anim1 forKey:#"transform"];
[self.view.layer addSublayer:orbit1];
// Orbit #2
CALayer *orbit2 = [CALayer layer];
orbit2.bounds = CGRectMake(0, 0, 120, 120);
orbit2.position = planet1.position;
orbit2.cornerRadius = 60;
orbit2.borderColor = [UIColor blueColor].CGColor;
orbit2.borderWidth = 1.5;
CALayer *planet2 = [CALayer layer];
planet2.bounds = CGRectMake(0, 0, 16, 16);
planet2.position = CGPointMake(60, 0);
planet2.cornerRadius = 8;
planet2.backgroundColor = [UIColor blueColor].CGColor;
[orbit2 addSublayer:planet2];
CABasicAnimation *anim2 = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
anim2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
anim2.fromValue = [NSNumber numberWithFloat:0];
anim2.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
anim2.repeatCount = HUGE_VALF;
anim2.duration = 4.0;
[orbit2 addAnimation:anim2 forKey:#"transform"];
[orbit1 addSublayer:orbit2];
// Orbit #3
CALayer *orbit3 = [CALayer layer];
orbit3.bounds = CGRectMake(0, 0, 72, 72);
orbit3.position = planet2.position;
orbit3.cornerRadius = 36;
orbit3.borderColor = [UIColor grayColor].CGColor;
orbit3.borderWidth = 1.5;
CALayer *planet3 = [CALayer layer];
planet3.bounds = CGRectMake(0, 0, 12, 12);
planet3.position = CGPointMake(36, 0);
planet3.cornerRadius = 6;
planet3.backgroundColor = [UIColor grayColor].CGColor;
[orbit3 addSublayer:planet3];
CABasicAnimation *anim3 = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
anim3.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
anim3.fromValue = [NSNumber numberWithFloat:0];
anim3.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
anim3.repeatCount = HUGE_VALF;
anim3.duration = 2.0;
[orbit3 addAnimation:anim3 forKey:#"transform"];
[orbit2 addSublayer:orbit3];