I have created a rectangle like this in objective -c :
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillRect(context, CGRectMake(0, 440, 320, 30));
}
in the view controller i have created a function which then calls this rectangle and an animation block so it looks like its coming out by the alpha command :
PopUpRectangle *RectangeView = [[PopUpRectangle alloc] initWithFrame:CGRectMake(0, 538, 320, 30)];
RectangeView.alpha = 0;
[self.view addSubview:RectangeView];
[UIView animateWithDuration:1.5
animations:^ {
RectangeView.alpha = 1;
}];
I have a function that is triggered by an event and then I call the above code to create the rectangle on the screen.
but how do i revert the action, would it be best to create another rectangle which brings the alpha back to 0 ?
thanks
Keep a local reference to RectangeView so you when you want you can animate it back out, and remove it from the view.
[UIView animateWithDuration:1.5
animations:^ {
RectangeView.alpha = 0;
} completion:^(BOOL finished) {
[RectangleView removeFromSuperview];
}];
You could also move your animation block to it's own function.
Like the other comment suggests save a local reference to it so that you can access it later.
- (void)animateBlock{
[UIView animateWithDuration:1.5
animations:^ {
RectangeView.alpha = !RectangleView.alpha; //Reverse the current alpha
} completion:^(BOOL finished) {
[RectangleView removeFromSuperview];
}];
}
Related
I have created custom buttons and worked with custom UIViews in the past. However I am not sure how to go about with this.
I am trying to create something similar to the twitter heart animation.
What I am unable to get is those tiny colored circles around the heart as shown in this gif:
https://dribbble.com/shots/2416983-Twitter-Heart-Animation
Any ideas?
Also is it possible for me to simply have a gif and add the gif as a custom view in a UIButton and play the gif when button is pressed?
Here's a concept:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIView *bubble = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 16.0, 16.0)];
bubble.layer.cornerRadius = 8.0;
bubble.center = self.view.center;
bubble.backgroundColor = [UIColor greenColor];
[self.view addSubview:bubble];
UIView *heart = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, 100.0, 100.0)];
heart.layer.cornerRadius = 50.0;
heart.center = self.view.center;
heart.backgroundColor = [UIColor blueColor];
[self.view addSubview:heart];
[UIView animateKeyframesWithDuration:2.0
delay:0.0
options:UIViewKeyframeAnimationOptionRepeat
animations:^{
// Heart expands
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.10 animations:^{
heart.transform = CGAffineTransformMakeScale(1.3, 1.3);
}];
// Heart contracts.
[UIView addKeyframeWithRelativeStartTime:0.15 relativeDuration:0.25 animations:^{
heart.transform = CGAffineTransformMakeScale(1.0, 1.0);
}];
// Bubble travels.
[UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.4 animations:^{
CGPoint destination = self.view.center;
destination.x += 100;
destination.y -= 100;
bubble.center = destination;
}];
// Bubble shrinks.
[UIView addKeyframeWithRelativeStartTime:0.6 relativeDuration:0.2 animations:^{
bubble.transform = CGAffineTransformMakeScale(0.3, 0.3);
}];
// Bubble fades.
[UIView addKeyframeWithRelativeStartTime:0.8 relativeDuration:0.2 animations:^{
bubble.alpha = 0.0;
}];
} completion:nil];
}
To get the full effect, you will need to add any a few more key frames so the bubble curves around before the fade. Given that you have a couple of bubbles, it might be a good idea to create a key frame generator.
Alternatively, you can use SKEmitterNode and add real particles to your button.
Late Answer but useful to other developers.
Here is the Link for exact same animation: https://github.com/xhamr/fave-button
Same Animation in Objective-C also: https://github.com/tljackyi/fave-button
I want to make something like this:
Reference of image.
What I do: two UIImagesView, one with UIViewContentModeLeft and another with UIViewContentModeRight. I have a slider where I can change image frames. The solution seems to be ok, but I am not sure if this is the "right" one. Other suggestions are welcome.
Thanks!
use single Imageview for your concept it is my suggestion If you feel free use this else use your concept else go some thirdparty, where you need for modify the transparent, add the one Transparent UIView above the ImageView . set the frame as of Transparent UIView for Show as (0, 0, ImageView.frame.size.width/2,ImageView.frame.size.height) , for Hide (ImageView.frame.origin.X - 40, 0, ImageView.frame.size.width/2,ImageView.frame.size.height)
for example
To Show
TransparentView.hidden = NO;
TransparentView.alpha = 0.1;
[UIView animateWithDuration:0.25 animations:^{
TransparentView.frame = CGRectMake(0,
0,
ImageView.frame.size.width/2,
ImageView.frame.size.height);
TransparentView.alpha = 1.0f;
} completion:^(BOOL finished) {
// do some
}];
To hide
[UIView animateWithDuration:0.25 animations:^{
TransparentView.frame = CGRectMake(0 - self.view.frame.size.width,
0,
ImageView.frame.size.width/2,
ImageView.frame.size.height);
[TransparentView setAlpha:0.1f];
} completion:^(BOOL finished) {
TransparentView.hidden = YES;
}];
Much like other apps, my app has a "welcome" page controller with a quick overview of the features. During this overview, I draw a UITabBar and have a circle show where the relevant feature is seen below:
I draw the circle using the following code that is executed every time a page is drawn:
double circleSize = 75;
[circleView removeFromSuperview];
circleView = [[UIView alloc] initWithFrame:CGRectMake(circleX,
circleY,
circleSize,
circleSize)];
circleView.layer.cornerRadius = (circleSize / 2);
circleView.layer.borderColor = [UIColor VancityTransitBlue].CGColor;
circleView.layer.borderWidth = 2;
I wish to have this circle appear to "breath" (grow slowly then shrink back to its original size). I use the exact code from my answer to this question:
[UIView animateWithDuration:1
delay:0
options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat
animations:^{
circleView.transform = CGAffineTransformMakeScale(1.5, 1.5);
}
completion:nil];
This circle is shared across three pages of the page controller and draws just fine. The animation works just fine on the first page, periodically works on the second page, and never works on the third page.
How can I have the animation play on every page for every circle view?
Here is a solution that works across all tabs. The animation can be moved around while in progress. You may want to use a better mechanism to manage the animation so that it can be cancelled efficiently. The code below is implemented in the Tab Controller. Ensure -showOverTabBarItem: and -hideCircleView are executed on main thread. It has been built, linked, ran and tested.
Show
-(void)showOverTabBarItem:(CGFloat)x {
[self hideCircleView];
self.circleView.frame =({
CGRect frame = self.circleView.frame;
frame.origin.x = x;
frame;
});
[self.view addSubview:self.circleView];
[UIView animateWithDuration:1
delay:0
options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat
animations:^{
self.circleView.transform = CGAffineTransformMakeScale(1.5, 1.5);
}
completion:nil];
}
Hide
-(void)hideCircleView
{
[self.circleView removeFromSuperview];
}
Initialize
Such as in viewDidLoad.
double circleSize = 75;
CGFloat circleY = self.view.bounds.size.height-(circleSize/2);
self.circleView = [[UIView alloc] initWithFrame:CGRectMake(0,
circleY,
circleSize,
circleSize)];
self.circleView.layer.cornerRadius = (circleSize / 2);
self.circleView.layer.borderColor = [UIColor blueColor].CGColor;
self.circleView.layer.borderWidth = 2;
Invoke
Pass the horizontal position to your animation: [self showOverTabBarItem: self.view.bounds.size.width/2];
Keep the view around
This is a critical step: when your -removeFromSuperView, you want to make sure that the object does not get recycled.
#interface TabController ()
#property (nonatomic, retain) UIView * circleView;
#end
Why have you alloc the circle every time a page drawn?
You can remove these lines (just need these for the first init):
if (circleView == nil) {
circleView = [[UIView alloc] initWithFrame:CGRectMake(circleX,
circleY,
circleSize,
circleSize)];
circleView.layer.cornerRadius = (circleSize / 2);
circleView.layer.borderColor = [UIColor VancityTransitBlue].CGColor;
circleView.layer.borderWidth = 2;
}
For add to another page: remove from current page
[circleView removeFromSuperview];
[circleView.layer removeAllAnimations];
and then add it to another page:
[self.view addSubView:circleView];
[UIView animateWithDuration:1
delay:0
options:UIViewKeyframeAnimationOptionAutoreverse | UIViewKeyframeAnimationOptionRepeat
animations:^{
circleView.transform = CGAffineTransformMakeScale(1.5, 1.5);
}
completion:nil];
Hi guys i have a quick question
I am using xcode to build an app and I want to animate the size of a custom rectangle during runtime.
I have a UIView class where i create custom rectangles and draw them on the screen of the ViewController. The problem is, whenever i start the app, it just create all the rectangles and then shows the screen.
What i want it to do is to show the screen and then animate the rectangles (like a "growing-animation")
This is how i create the rectangles in the UIView class
-(void)newRectWithX:(int) x height:(int) height{
_rdmRed = arc4random_uniform(100);
_rdmRed /= 100;
_rdmGreen = arc4random_uniform(100);
_rdmGreen /= 100;
_rdmBlue= arc4random_uniform(100);
_rdmBlue /= 100;
_color = [UIColor colorWithRed:_rdmRed green:_rdmGreen blue:_rdmBlue alpha:0.6];
[UIView animateWithDuration:50 delay:10 options:UIViewAnimationOptionShowHideTransitionViews
animations:^{
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rectangle = CGRectMake(x,0,4,height);
CGContextAddRect(context, rectangle);
CGContextSetFillColorWithColor(context, [_color CGColor]);
CGContextFillRect(context, rectangle);
}
completion:nil];
}
I didn't do anything in the ViewController class yet.
+ animateWithDuration:delay:options:animations:completion:
Animate changes to one or more views using the specified duration, delay, options, and completion handler.
To be able to use that method you will need to animate a view. Here is a chuck of code that will allow you to use that method and CoreGraphics.
#implementation View
{
UIView * view;
}
- (void)runAnimation {
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:#selector(setNeedsDisplay) userInfo:nil repeats:YES];
view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 10)];
[UIView animateWithDuration:1 delay:0 options:UIViewAnimationOptionShowHideTransitionViews animations:^{
view.frame = CGRectMake(0, 0, 20, 20);
} completion:nil];
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGRect rectangle = ((UIView *)[view.layer presentationLayer]).frame;
CGContextAddRect(context, rectangle);
CGContextSetFillColorWithColor(context, [UIColor cyanColor].CGColor);
CGContextFillRect(context, rectangle);
}
#end
I have this to move a rectangle, maybe can help you
if(destination.origin.x > 0){
destination.origin.x = 0;
[self.navigationController.view.superview bringSubviewToFront:self.navigationController.view];
}else{
destination.origin.x += _sideMenu.view.frame.size.width;
}
[UIView animateWithDuration:0.2 animations:^{
self.view.frame = destination;
}completion:^(BOOL finished) {
if(finished){
if (destination.origin.x > 0) {
[self.navigationController.view.superview bringSubviewToFront:_sideMenu.view];
} else {
}
}
}];
change the destination.origin to destination.size, like this
CGRect destination = self.view.frame;
if(destination.size.height > 10){
destination.size.height = 10;
[self.navigationController.view.superview bringSubviewToFront:self.navigationController.view];
}else{
destination.size.height += 10;
}
[UIView animateWithDuration:0.2 animations:^{
self.view.frame = destination;
}completion:^(BOOL finished) {
if(finished){
if (destination.size.height > 10) {
[self.navigationController.view.superview bringSubviewToFront:_sideMenu.view];
} else {
}
}
}];
I'm trying to translate a UIView for a distance using the following code:
CGAffineTransform transform = CGAffineTransformMakeTranslation(-100, -100);
[self.exposureHintView setTransform:transform];
[UIView animateWithDuration:2.0
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
NSLog(#"Begin!");
CGAffineTransform newTrans = CGAffineTransformMakeTranslation(0, 0);
[self.exposureHintView setTransform:newTrans];
}
completion:^(BOOL finished) {
NSLog(#"End %d", finished);
}];
So basically, I'm justing trying to move the view from some point say (-100, -100) to where it should be (0, 0) relative to itself.
Since I wanted to animate it once the view appeared, so I put the code in viewDidAppear:. But when I run the code, nothing happened.
The self.exposureHintView here is a custom subclass of UIView, does it matter?
Why?
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
[_AboutView setFrame:CGRectMake(0, 0, 320, 510)];
[UIView commitAnimations];
Use this code to change the position of your view
I think the problem here is you are create exposureHintView in storyboard or XIB file without code programmatically.
Try to do as the follows:
- (void)viewDidLoad
{
//Init exposureHintView
UIView* exposureHintView = [[UIView alloc]initWithFrame(sampleFrame)];
[self addSubView: exposureHintView];
//Set transform
CGAffineTransform transform = CGAffineTransformMakeTranslation(-100, -100);
[self.exposureHintView setTransform:transform];
//Commit animation
[UIView animateWithDuration:2.0 delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
NSLog(#"Begin!");
CGAffineTransform newTrans = CGAffineTransformMakeTranslation(0, 0);
[self.exposureHintView setTransform:newTrans];
}
completion:^(BOOL finished) {
NSLog(#"End %d", finished);
}];
The reason here is your could not set Frame or Transform or some another attribute of this UIView in >>ViewDidLoad when you using storyboard or XIB