Creating image which sweeps across the screen - ios

I'm trying to create a banner that sweeps across the current scene. I want to create a banner which sweeps down the screen to show the current round. My attempt at it is creating a UIImageView and add it to the current view. However, i assume its calling the didMoveToView Function and resetting everything in that scene, which is something i dont want it to do. Here is my attempt:
-(void)createBanner{
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Banner"]];
[imageView setFrame:CGRectMake(0,0, imageView.frame.size.width, imageView.frame.size.height)];
[imageView setClipsToBounds:YES];
[self.view addSubview:imageView];
CABasicAnimation *sweep = [CABasicAnimation animationWithKeyPath:#"position"];
sweep.fromValue = [NSValue valueWithCGPoint:CGPointZero];
sweep.toValue = [NSValue valueWithCGPoint:CGPointMake(0.0, self.frame.size.height)];
sweep.duration = 10;
sweep.additive = YES;
[imageView.layer addAnimation:sweep forKey:#"sweep"];
}
EDIT: i am using sprite kit in order to create the game.

As hamobi said, it's best to use an 'SKSpriteNode' in Sprite Kit and not UIKit. Assuming your'e adding to an 'SKScene', your code above translated to Sprite Kit is:
-(void)createBanner{
SKSpriteNode* spriteNode = [SKSpriteNode spriteNodeWithImageNamed:#"Banner"]
//It's good practice not to resize the sprite in code as it should already be the right size but...
spriteNode.size = CGSizeMake(self.size.width, self.size.height)
//Set its center off to the left of the screen for horizontal sweep, or you can do vertical and set it off the top of the screen...
spriteNode.postion = CGPointMake(-spriteNode.size.width/2, self.size.height/2)
self.addChild(spriteNode)
//Then to sweep from left to right...
SKAction* sweep = [SKAction moveTo:CGPointMake(spriteNode.size.width/2, self.size.height/2) duration:10]
spriteNode.runAction(sweep)
}
I think that covers most of it.

Related

Disable change of a spritenode

I'm creating a game where i'm creating an SKSpriteNode at the bottom. Cause i want to make a buttom higher than the actually bottom cause of grass as the background. The problem is after I've created the physics body and my moving SKSpriteNode makes contact with the bottom. the bottom SpriteNode that i've created will move.
How can i make the bottom sprite node which has the function as being the bottom edge, not move at all. By that i mean that it cant change position.
My code:
SKSpriteNode *bottom = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor] size:CGSizeMake(self.frame.size.width*2, 98)];
bottom.physicsBody.dynamic = NO;
bottom.position = CGPointMake(0, 0);
[self addChild:bottom];
bottom.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bottom.size];
You have to set the dynamic property of the physics body to NO. You are doing it before you actually create a physics body. That's why it does not have any effect. Change your code to:
SKSpriteNode *bottom = [SKSpriteNode spriteNodeWithColor:[SKColor clearColor]
size:CGSizeMake(self.frame.size.width*2, 98)];
bottom.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bottom.size];
bottom.physicsBody.dynamic = NO;
bottom.position = CGPointMake(0, 0);
[self addChild:bottom];
And it should work.

Spritekit / UIBeziers: Detecting touches / nodeAtPoint

I'm creating my player like this:
UIBezierPath *pPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(0, 0)
radius:10
startAngle:0
endAngle:DEGREES_TO_RADIANS(360)
clockwise:YES];
_player = [[SKShapeNode alloc] init];
_player.path = pPath.CGPath;
[_player setFillColor:[UIColor blueColor]];
[_player setStrokeColor:[UIColor clearColor]];
_player.position = arenaCentre;
_player.zPosition = 1;
_player.name = #"player";
I then detect touches on this object using:
SKSpriteNode *touchedNode = (SKSpriteNode *)[self nodeAtPoint:touchLocation];
The problem is that my shape is too small/ fast to touch sometimes. How could I make the touch zone larger then the visible object?
Is there a best practice for this kind of thing?
Many thanks,
Ian
You could draw a larger shape (or color sprite) of the desired size as the parent of the player shape, and use a fully transparent color.
However this will sometimes find the parent shape, other times the actual shape. So you have to compensate for that.

Rotating a view around a fixed point - ObjectiveC

I need to rotate a UIView around a fixed point.
bubbleTail = [[BubbleTail alloc] initWithFrame:bubbleTailFrame];
[self addSubview:bubbleTail];
bubbleTail.layer.anchorPoint = triangle_top_left;
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI * 180 / 180.0);
bubbleTail.transform = transform;
This works only if I comment the .anchorPoint line.
How do I rotate the view about a point inside the view?
The below should help. The tricky part is that setting the anchorpoint after adding a view with a frame then moves the view. I've gotten around this by initiating the UIView without a frame, then setting the position, bounds and anchorpoint of its layer. I then use the rotation to rotate around the anchor point.
CABasicAnimation *rotation;
rotation = [CABasicAnimation animationWithKeyPath:#"transform.rotation"];
rotation.fromValue = [NSNumber numberWithFloat:0];
rotation.toValue = [NSNumber numberWithFloat:((360*M_PI)/180)];
rotation.duration = 60.0;
rotation.repeatCount = HUGE_VALF;
UIView *myview = [[UIView alloc] init];
[self.view addSubview:myview];
[myview setBackgroundColor:[UIColor orangeColor]];
[myview.layer setPosition:CGPointMake(10, 10)];
[myview.layer setBounds:CGRectMake(0, 0, 100, 100)];
[myview.layer setAnchorPoint:CGPointMake(0, 0)];
[myview.layer addAnimation:rotation forKey:#"myAnimation"];
Someone please correct me if this is not the best method or if there are mistakes - I only know what I currently know - e.g. when I should use a . or f after a float.
So it seems CGAffineTransformMakeRotation rotates it around the center of the view?
Say you have point P (px,py) in view, you want view to be rotated around that.
Let's A(ax,ay) = P - center = (px - centerx, py - centery).
And you have angle alpha.
Then you could make a translate matrix with - A, then multipy it with rotation matrix with alpha, then multipy it with translate matrix with + A.
The functions you'll need are: CGAffineTransformMakeTranslation, CGAffineTransformMakeRotation, CGAffineTransformConcat.
P.S. Not sure if this will work (also not sure how view rect is represented, maybe it first assumption about rotation around center is wrong, then you shoud assume A = P), but that's how it's done with affine transforms.

iOS slide up an image over an image, revealing the underneath one. (A-la jQuery.slide())

I'm trying to do the following thing -
I have two version of the same image, one colored and one black and white. I want the B&W to "Slide up" revealing the one under it.
I tried setting the height and the frame, but couldn't get it to work like I want it to.
For example , this would be a combination of both UIImages where one is revealing the other, while not moving:
Any ideas? :)
OK, here is a different method using a mask on the grey view. I actually tested this with a blueView and a greyView, where the grey covers up the blue. Put a mask layer on the grey layer so that the grey layer is visible. Now animate the mask away from the grey layer, making the grey layer disappear without moving it, the blue shows thru where the grey disappears.
If you want to experiment with this, create an empty project in XCode with a single view, and put this code inside viewDidLoad. That's how I tested this.
self.view.backgroundColor = [UIColor whiteColor];
UIView* blueView = [[[UIView alloc] init] autorelease];
blueView.backgroundColor = [UIColor blueColor];
blueView.frame = CGRectMake(50,50,100,100);
UIView* grayView = [[[UIView alloc] init] autorelease];
grayView.backgroundColor = [UIColor grayColor];
grayView.frame = CGRectMake(50,50,100,100);
[self.view addSubview:blueView];
[self.view addSubview:grayView]; // gray covers the blue
// Create a mask to allow the grey view to be visible and cover up the blue view
CALayer* mask = [CALayer layer];
mask.contentsScale = grayView.layer.contentsScale; // handle retina scaling
mask.frame = grayView.layer.bounds;
mask.backgroundColor = [UIColor blackColor].CGColor;
grayView.layer.mask = mask;
// Animate the position of the mask off the grey view, as the grey becomes unmasked,
// that part of the grey "dissappears" and is no longer covering the blue underneath
CABasicAnimation* a = [CABasicAnimation animationWithKeyPath:#"position"];
a.duration = 4;
a.fromValue = [NSValue valueWithCGPoint:mask.position];
CGPoint newPosition = mask.position;
newPosition.y += mask.bounds.size.height;
a.toValue = [NSValue valueWithCGPoint:newPosition];
a.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
[mask addAnimation:a forKey:#"colorize"]; // animate presentation
mask.position = newPosition; // update actual position
Don't forget this line at the top with the #imports:
#import <QuartzCore/QuartzCore.h>
One way is to stack the UIView's so that the B&W image on top of the color image, where the color image is completely covered (hidden) by the B&W image.
[self.view insertSubview:bwImage aboveSubview:colorImage];
Only the B&W view is visible. Now set clipsToBounds on the B&W view:
bwImage.clipsToBounds = YES;
Finally animate the height in the bounds of the bwImage so that its height shrinks down to 0, clipping the B&W image and revealing the color image behind it. Something like this:
[UIView animateWithDuration:1.0 animations:^{
CGRect b = bwImage.bounds;
b.size.height = 0;
bwImage.bounds = b;
}];
I haven't tried this but hopefully you get the idea.

Line is not smooth on layer.border when its rotated

I need to rotate an UIImageView:
UIImageView *img = [[UIImageView alloc] init];
img.layer.borderWidth = 3.0;
img.layer.borderColor = UIColorFromRGB(0xffffff).CGColor;
img.layer.shadowColor = UIColorFromRGB(0x000000).CGColor;
CATransform3D transform = CATransform3DMakeRotation ([Helper degreesToRadians:(5)], 1, 1, 1);
img.layer.shadowRadius = 2.0;
img.layer.shouldRasterize = YES;
The problem is that the border is not smooth at all:
Try adding a transparent border (1px may be) around your image. See this link.
Check UIImage+Alpha section in that page.
I see most of the answer for this problem is to add 1px transparent border but it only works if we are not using any border around UIImageView, if UIImageView itself has the border and we rotate it then the border is not smooth. I am stil trying to figure out on how to fix that issue.
HERE'S WHAT I DID TO FIX THIS ISSUE
UIImage *thumbnail = [photo thumbnailImage:thumbnailSize.width
transparentBorder:2
cornerRadius:0
interpolationQuality:kCGInterpolationHigh];
CGPoint randomPoint = [self getRandomOriginPoint];
UIImageView *thumbnailView = [[UIImageView alloc] initWithFrame:CGRectMake(10.0, 10.0, thumbnail.size.width, thumbnail.size.height)];
[thumbnailView.layer setBorderWidth:2];
[self setContentMode:UIViewContentModeCenter];
[thumbnailView.layer setBorderColor:[UIColor whiteColor].CGColor];
[thumbnailView.layer setShadowOffset:CGSizeMake(-3.0, 3.0)];
[thumbnailView.layer setShadowRadius:3.0];
[thumbnailView.layer setShadowOpacity:1.0];
thumbnailView.layer.shouldRasterize = YES;
I used UIImage+Resize.h from here to get the thumbnail image in my code, so with this even after you rotate image with any angle the border will look perfectly fine!
Without having to use categories, solution that made the fewest presumptions
#import <QuartzCore/QuartzCore.h>
We will use the following variable
UIView *myView;
This has been confirmed to work on UIImageViews / UIViews of all types
myView.layer.shouldRasterize = YES; //the single line that solved this problem from the above
You should not need to add a border of any type for this to work.
CATransform3D rotate = CATransform3DIdentity;
myView.layer.shouldRasterize = YES;
rotate = CATransform3DRotate(rotate,M_PI_4/8,0.0,0.0,1);
myView.layer.transform = rotate;
Note: This answer is provided to consolidate the information into a single answer that removes some of the other requirements. In this example I use M_PI_4/8 as it's a nice viewing angle for if you have a Stickie Note sort of view that you are implementing.

Resources