Image Changing CALayer Core Animation - ios

What is the best way of changing the image of my "Sprite" before/during/after an animation?
I display the image:
CALayer *am = [[CALayer alloc] init];
am.contents = img;
am.bounds = CGRectMake(150, 150, 46, 47);
[self.view.layer addSublayer:am];
[am setNeedsDisplay];
Say I have an animation that takes the sprite from location A to Location B, how would I change the image of the layer the second it hits Location B, or leaves Location A?
Thank you!!

You can use sprite sheet or can follow this way of adding into plist file .
http://www.raywenderlich.com/1271/how-to-use-animations-and-sprite-sheets-in-cocos2d
(without cocos2d) If you want to manually give frames then this tutorial is best. Provides with source code too, enjoy . http://mysterycoconut.com/blog/2011/01/cag1/

Related

how to implement this animation in iOS?

I am not sure about how to present this question because I don't know the animation term that I should use.
I need to know about this tree presentation animation. As it is appearing form root to top.
Please take a look on attached .gif file and let me know if anyone know about this animation or if you can guide me with example.
I will really appreciate.
Thanks for your time.
The best option for you is to split up the gif into multiple images and then do the following:
NSArray *gifImagesArray = [NSArray arrayWithObjects:imageOne, imageTwo, imageThree, nil];
imageView.animationImages = animateImagesArray;
imageView.animationRepeatCount = 1;
imageView.animationDuration = 1.0f;
[imageView startAnimating];
Edit following comments:
If you can't use multiple images you have to write the animation yourself.
One suggestion is to add a circular mask to the UIImage and animate it's removal.
This link explains how to draw a circular CALayer: Circular Progress Bars in IOS
This one here will show you how to create a mask on a UIImage: Simply mask a UIView with a rectangle
now all you have to do is a simple animation.
I have a solution that will work for this problem.
We can use gif image and convert it into UIImage object. So image object will work same as animation.
Thanks all for your answers.
In my opinion, I will separate this animation to 4 parts:
animation to show full black tree from center.
animation to show Texts
animation to show blue leafs.
animation to show 2 buttons at bottom.
You can use this framework https://github.com/facebook/pop to operate all animations step by step or even Core Animation.
Please do more research... I think you will success to make one.
You can achieve this animation using simple UIImageView, that can load multiple images using animationImages property of UIImageView.
First, create one NSMutablerArray of images.
then asssign that images to imageView, and animationDuration for that images.
UIImageView *animationImageView = [[UIImageView alloc] initWithFrame:CGRectMake(60, 95, 86, 193)];
animationImageView.animationImages = images;
animationImageView.animationDuration = 0.5;
add the imageview to view.
[self.view addSubview:animationImageView];
[animationImageView startAnimating];

Making transparent Circles in iOs

I want to create a black UIView with transparent circles.
I think about create one view (with black color and transparence 50%), and add multiple circles inside of it, but I don't know how to set the transparence for each. I know how to create a circle View (an example: how to draw a custom uiview that is just a circle iphone-app).
I want to do is something like iShowcase library but with multiple dots:
Any clue? thanks.
SOLVED
I took a look to the code of iShowcase library and I solved my probblem. now, I am working in a library based in iShowcase library.
I will post here when I finish it.
Please have a look of below link hope this will helpful for you.
Link : Here is Answer to set shadow in your view.
Use alpha for your circleView. As in your link example,then add as subviews in yourmainview:
UIView *circleView = [[UIView alloc] initWithFrame:CGRectMake(10,20,100,100)];
circleView.alpha = 0.5;
circleView.layer.cornerRadius = 50;
circleView.backgroundColor = [UIColor whiteColor];
[yourmainview addSubview: circleView];
Btw in your picture I think white circles have 100% alpha. You can use individual alpha for each circleView, or use a randomizer :)
As for updated example why don't you add more buttons and showcase in your h file, synthesize them and use multiple instances .... showcase setupShowcaseForTarget:btn_custom_1 title:#"title" details:#"other"]; ? I think you should modify main classes, becouse what you want are different containerView for multiple views [circles].
Using modifyed iShowcase.m [- (void) calculateRegion], and different views as containers, I was able to make something like: http://tinypic.com/view.php?pic=2iwao6&s=8#.VLPTRqYsRE8 So the answer is: use custom views for multiple showcase [ex [showcase2 setContainerView:self.view2];], then custom frame for each showcase [ showcase2.frame = CGRectMake(0,0,100,100);] I don;t habe time to fine tuning the example, but yes, you can achieve desired result...
I finally solved my question inspired by iShowCase library I did this simple class and Upload to github.
https://github.com/tato469/FVEasyShowCase
Simplest what you can do is to have your main view (black 50% transparant) and add shapes to the mask layer of that.
So basically:
//Set up your main view.
UIView* mainView = [UIView new];
mainView.backgroundColor = [UIColor blackColor];
mainView.alpha = 0.5;
UIView* circle1 = [YourCircleClassHere new];
UIView* circle2 = [YourCircleClassHere new];
UIView* circle3 = [YourCircleClassHere new];
UIView* container = [UIView new];
[UIView addSubview:circle1];
[UIView addSubview:circle2];
[UIView addSubview:circle3];
//Make a new layer to put images in to mask out
CALayer* maskLayer = [CALAyer layer];
//Assign the mask view to the contents layer.
maskLayer.contents = (id)container;
//This will set the mask layer to the top left corner.
maskLayer.frame = CGRectMake(0,0,container.frame.size.width,container.frame.size.height);
//Lastly you assign the layer to the mask layer of the main view.
mainView.layer.mask = maskLayer;
//Applies basically the same as clipToBounds, but a bit reversed..
mainView.layer.mask = true/false;
On a sidenote:
I achieved this with images "contents = (id) [UIImage CGImage]", but I'm sure it should work with UIViews as well.
Also mind some mistakes, since I just wrote this from my mind, also I didn't test this out.. So keep me updated if it works/!works ^_^

How to Clone A UIImageView

I have a UIImageView and I want to make a copy of it and place it somewhere on the screen. How do I do this?
I currently only know how to copy and paste the image manually and make a separate IBOutlet for each one, but this is very inefficient because I want to make a game that generates obstacles (UIImageViews) forever so I can't do it the manual way.
You want to make sure you match all of the properties up as well, like size, clipping, image aspect, opacity, etc.
CGPoint locationOfCloneImageView = CGPointMake(0, 0);//x and y coordinates of where you want your image. (More specifically, the x and y coordinated of where you want the CENTER of your image to be)
UIImageView *cloneImageView = [[UIImageView alloc] initWithImage:originalImageView.image];
cloneImageView.frame = CGRectMake(0, 0, originalImageView.frame.size.width, originalImageView.frame.size.height);//same size as old image view
cloneImageView.alpha = originalImageView.alpha;//same view opacity
cloneImageView.layer.opacity = originalImageView.layer.opacity;//same layer opacity
cloneImageView.clipsToBounds = originalImageView.clipsToBounds;//same clipping settings
cloneImageView.backgroundColor = originalImageView.backgroundColor;//same BG color
cloneImageView.tintColor = originalImageView.tintColor;//matches tint color.
cloneImageView.contentMode = originalImageView.contentMode;//matches up things like aspectFill and stuff.
cloneImageView.highlighted = originalImageView.highlighted;//matches whether it's highlighted or not
cloneImageView.opaque = originalImageView.opaque;//matches can-be-opaque BOOL
cloneImageView.userInteractionEnabled = originalImageView.userInteractionEnabled;//touches are detected or not
cloneImageView.multipleTouchEnabled = originalImageView.multipleTouchEnabled;//multi-touches are detected or not
cloneImageView.autoresizesSubviews = originalImageView.autoresizesSubviews;//matches whether or not subviews resize upon bounds change of image view.
//cloneImageView.hidden = originalImageView.hidden;//commented out because you probably never need this one haha... But if the first one is hidden, so is this clone (if uncommented)
cloneImageView.layer.zPosition = originalImageView.layer.zPosition+1;//places it above other views in the parent view and above the original image. You can also just use `insertSubview: aboveSubview:` in code below to achieve this.
[originalImageView.superview addSubview:cloneImageView];//adds this image view to the same parent view that the other image view is in.
cloneImageView.center = locationOfCloneImageView;//set at start of code.
You will need to create one new UIImageView with its new frame where you want to place it. set its image property of your existing imageView's image, and after that add it to your view.
UIImageView *newImageView = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,50,50)];
newImageView.image = oldImageView.image;
[self.view addSubView:newImageView]

Creating a UIButton in shape of the image given

how can i create a UIButton in shape of the image given.
i am able to create something close to it,but the image seems to be not fitting in the button.
my requirement is the image given below.i.e;semicircle
the code i used to create the button is given below.
what changes should i make on the following image to get this button.
ps-add subview done in another class..
btnStartGame =[UIButton buttonWithType:UIButtonTypeCustom];
[btnStartGame setFrame:CGRectMake(60, 200, 200, 200)];
btnStartGame.titleLabel.font=[UIFont fontWithName:#"Helvetica-Bold" size:30];
[btnStartGame setImage:
[UIImage imageNamed:#"Draw button.png"] forState:UIControlStateNormal];
btnStartGame.titleLabel.textColor=[UIColor redColor];
btnStartGame.clipsToBounds = YES;
btnStartGame.layer.cornerRadius = 50;//half of the width
btnStartGame.layer.borderColor=[UIColor redColor].CGColor;
btnStartGame.layer.borderWidth=2.0f;
btnStartGame.tag=20;
btnStartGame.highlighted=NO;
There is a really great tutorial here with downloadable source code:
http://iphonedevelopment.blogspot.co.uk/2010/03/irregularly-shaped-uibuttons.html
In essence you need to create a category on UIImage, which checks whether the point you have touched is transparent image or not. This means you can use it to check hit tests on irregular shapes.
You then subclass UIButton and over-ride the hitTest:withEvent:
Hope this helps
Although the solution by Jeff Lamarche linked by the other answer works fine, it uses a lot of memory, and/or does a lot of work:
If you create NSData once in the initializer, you end up holding a relatively large block of memory for the lifetime of each button
If you make it transient, the way it is done in the answer, then you end up converting the entire image each time you hit test your button - processing thousands of pixels and throwing away the result after fetching a single byte!
It turns out that you can do this much more efficiently, both in terms of memory use and CPU consumption, by following the approach outlined in this answer.
Subclass UIButton, and override its pointInside:withEvent: method like this:
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
if (![super pointInside:point withEvent:event]) {
return NO;
}
unsigned char pixel[1] = { 0 };
CGContextRef context = CGBitmapContextCreate(pixel, 1, 1, 8, 1, NULL, (CGBitmapInfo)kCGImageAlphaOnly);
UIGraphicsPushContext(context);
UIImage *image = [self backgroundImageForState:UIControlStateNormal] ;
[image drawAtPoint:CGPointMake(-point.x, -point.y)];
UIGraphicsPopContext();
CGContextRelease(context);
return pixel[0] != 0;
}
The code above takes alpha from the background image of the button. If your button uses another image, change the line that initializes image variable above.

renderInContext flips the origin of colorWithPatternImage

I have UIView with backgroundColor set with colorWithPatternImage. As expected, the background image is drawn starting at the top left corner.
Problem appears when I'm doing renderInContext on that view: the background image is drawn starting at the bottom left corner. Everything else seems to render fine.
Here's the source and destination images:
Here is the code:
// here is the layer to be rendered into an image
UIView *src = [[UIView alloc] initWithFrame:(CGRect){{0, 0}, {100, 100}}];
src.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background.png"]];
[self.view addSubview:src];
// here we'll display the image
UIImageView *dest = [[UIImageView alloc] initWithFrame:(CGRect){{110, 0}, src.bounds.size}];
[self.view addSubview:dest];
// render `src` to an image in `dest`
UIGraphicsBeginImageContext(src.bounds.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[src.layer renderInContext:context];
dest.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Is there a way to keep the image to tile in right direction, as in the src view?
I managed to work around this by calling CGContextSetPatternPhase with a height of modf(viewHeight, patternHeight)
https://developer.apple.com/library/ios/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_overview/dq_overview.html#//apple_ref/doc/uid/TP30001066-CH202-CJBBAEEC
This doc explains why this happens, in particular this part:
Important: The above discussion is essential to understand if you plan to write applications that directly target Quartz on iOS, but it is not sufficient. On iOS 3.2 and later, when UIKit creates a drawing context for your application, it also makes additional changes to the context to match the default UIKIt conventions. In particular, patterns and shadows, which are not affected by the CTM, are adjusted separately so that their conventions match UIKit’s coordinate system. In this case, there is no equivalent mechanism to the CTM that your application can use to change a context created by Quartz to match the behavior for a context provided by UIKit; your application must recognize the what kind of context it is drawing into and adjust its behavior to match the expectations of the context.

Resources