iOS development QQ Sticky animation effect

Source: Internet
Author: User

Sticky animation effects for QQ (IOS) clientstime 2016-02-17 16:50:00 Blog Park essence Area Original http://www.cnblogs.com/ziyi--caolu/p/5195615.html ThemeiOS Development

QQ App If there is a new contact to send messages, the corresponding contact of the cell to the right there will be a red circle to indicate the number of message bars. If you touch that circle, you can see that it moves with the movement of your finger.

Within a certain range, the finger leaves the screen and will find that the red circle will automatically bounce back to its original position. If a certain distance is exceeded, the circle will be destroyed by an animation that is removed from view.

Product requirements of the company's app also to have the effect, and spent some time to learn its implementation process, found that the principle is relatively simple.

(Because Mac makes GIF pictures is too cumbersome, so the effect is only to look at the picture.) )

Demo's github address: Https://github.com/wzpziyi1/QQ-Goo

Here are some pieces of the implementation process:

After analysis, it can be found that is two circles and an irregular rectangular position, the size of the change. At first, the small circle and the center of the big Circle is the same, when moving large circles, the radius of the small circle with the circle away from the small circle to become smaller, when the great circle distance small circle a certain distance, the small circle is hidden, the middle of the irregular rectangle removed.

So what does the irregular rectangle say? You can use the core graphics to draw the path of an irregular rectangle within the DrawRect method, and then use the color fill. The irregular rectangle is constantly changing with the movement of the great circle, and if it is drawn in the DrawRect method, the Setneedsdisplay method is repeatedly called to redraw during the move. This is a viable option, and I use it in general.

However, I did not draw in the DrawRect method, but the use of cashapelayer, the path of the irregular rectangle is drawn in Shapelayer, so that in the process of moving the great circle constantly updated Cashapelayer path.

Of course, the difficulty is here. It is the position of each point of the irregular rectangle. To draw this irregular rectangle, you need to know the position of six points:

With the coordinates of these points, you can use Uibezierpath to draw the corresponding path, the code is as follows:

- (Uibezierpath *) Pathwithbigcircleview: (UIView *) Bigcircleview Smallcircleview: (UIView *) smallcircleview{Cgpoint bigcenter = Bigcircleview.center;CGFloat x2 = bigcenter.x;CGFloat y2 = bigcenter.y;CGFloat r2 = bigCircleView.bounds.size.width/2;Cgpoint smallcenter = Smallcircleview.center;CGFloat x1 = smallcenter.x;CGFloat y1 = smallcenter.y;CGFloat r1 = smallCircleView.bounds.size.width/2;Get Center DistanceCGFloat d = [Self Distancewithpointa:bigcenter pointb:smallcenter];Θ: (Xita)CGFloat sinθ= (X2-X1)/D;CGFloat cosθ= (y2-y1)/D;coordinate system based on parent controlCgpoint Pointa =Cgpointmake (X1-R1 * cosθ, y1 + r1 * sinθθ);Cgpoint POINTB =Cgpointmake (x1 + r1 * cosθ, Y1-R1 * sinθθ);Cgpoint POINTC =Cgpointmake (x2 + r2 * cosθ, Y2-R2 * sinθθ);Cgpoint Pointd =Cgpointmake (X2-R2 * cosθ, y2 + r2 * sinθθ);Cgpoint Pointo =cgpointmake (pointa.x + d/2 * sinθθ, pointa.y + d/2 * cosθ); cgpoint pointp = cgpointmake (pointb.x + d/2 * sinθθ, pointb.y + d/2 * cosθ); uibezierpath *path = [uibezierpath BezierPath]; //A [path Movetopoint:pointa]; //AB [path ADDLINETOPOINT:POINTB]; //plot BC curve [path ADDQUADCURVETOPOINT:POINTC CONTROLPOINT:POINTP]; //CD [path ADDLINETOPOINT:POINTD]; //draw da Curve [path Addquadcurvetopoint:pointa controlpoint:pointo]; return Path;}            

In the implementation process, I am a custom UIButton, it is important to note that when you listen to the button drag, it is best to add uipangesturerecognizer gesture to it, and not in the Touchesbegin method to determine its moving position, Because the touches series method masks the click of a button.

The custom button is a large circle, which contains a small circle (UIView) property, but the small circle is not added to the custom button (that is, the great circle) but to the superview of the button. Because the small circle does not need to change position with the change of the great circle position, the Shapelayer is also added to the button (large circle) on the parent control.

A pan gesture was added to the great circle, and in the pan: method the size of the small circle is changed and the path of the Shapelayer is drawn.

When the pan gesture state is end, it is necessary to determine whether the distance between the large circle and the small circle exceeds the maximum distance, and if it is exceeded, add a GIF to play the process of destroying the great circle. If not destroyed, then the great circle needs to be reset, the corresponding code:

#import"ZYGooView.h"#define KMAXDISTANCE 100@interfaceZygooview ()@property (Nonatomic,WeakUIView *smallcircleview;@property (Nonatomic,AssignCGFloat Smallcircler;@property (Nonatomic,WeakCashapelayer *shapelayer;@end@implementationzygooview-(Instancetype) initWithFrame: (CGRect) frame{if (Self = [Super Initwithframe:frame]) {[Self Commitinit]; }ReturnSelf;} - (void) awakefromnib{[Self commitinit];} - (void) commitinit{Self.layer.cornerRadius =Self.frame.size.width *0.5;Self.layer.masksToBounds =YES;Self.smallcircler =Self.frame.size.width *0.5;Self.smallCircleView.bounds =Self.bounds;Self.smallCircleView.center =Self.center;Self.smallCircleView.layer.cornerRadius =Self.smallCircleView.frame.size.width *0.5; [Self addgesture];}#pragma mark----Lazy loading Method-(UIView *) smallcircleview{if (_smallcircleview = =Nil) {UIView *view = [[UIView alloc] init]; View.backgroundcolor =Self.backgroundcolor; [Self.superview Addsubview:view]; [Self.superview Insertsubview:view Atindex:0]; _smallcircleview = view; }return _smallcircleview;} - (Cashapelayer *) shapelayer{if (_shapelayer = =Nil) {Cashapelayer *shapelayer = [Cashapelayer layer]; Shapelayer.path = [Self Pathwithbigcircleview:Self Smallcircleview:Self.smallcircleview]. Cgpath; Shapelayer.fillcolor =Self.backgroundColor.CGColor; [Self.superview.layer Addsublayer:shapelayer]; [Self.superview.layer Insertsublayer:shapelayer Atindex:0]; _shapelayer = Shapelayer; }return _shapelayer;}#pragma mark----Other methods-(void) addgesture{Uipangesturerecognizer *recognizer = [[Uipangesturerecognizer Alloc] Initwithtarget:Self action:@selector (pan:)]; [Self Addgesturerecognizer:recognizer];} - (void) Pan: (Uipangesturerecognizer *) recognizer{Cgpoint point = [Recognizer Translationinview:Self.superview];Cgpoint Center =Self.center; Center.x + = Point.x; Center.y + = Point.y;Self.center = center;Reset [recognizer Settranslation:Cgpointzero InView:Self];CGFloat distance = [Self Distancewithpointa:Self.smallCircleView.center POINTB:Self.center];if (distance = =0)ReturnCGFloat NEWR =Self.smallcircler-distance/15.0;NSLog (@ "%f", NEWR);Self.smallCircleView.bounds =CGRectMake (0,0, NEWR *2, NEWR *2);Self.smallCircleView.layer.cornerRadius = NEWR;if (Distance > kmaxdistance | | newr <=0) {Self.smallCircleView.hidden =YES; [Self.shapelayer Removefromsuperlayer];Self.shapelayer =Nil }if (distance <= kmaxdistance &&Self.smallCircleView.hidden = =NO) {Self.shapeLayer.path = [Self Pathwithbigcircleview:Self Smallcircleview:Self.smallcircleview]. Cgpath; }if (recognizer.state = =uigesturerecognizerstateended) {if (distance <= kmaxdistance) {dispatch_after (Dispatch_time (Dispatch_time_now) (int64_t) (0.03 *NSEC_PER_SEC)), Dispatch_get_main_queue (), ^{[Self.shapelayer Removefromsuperlayer];Self.shapelayer =Nil }); [UIView animatewithduration:0.4 delay:0 usingspringwithdamping:0.6 initialspringvelocity:0 Options:Uiviewanimationoptioncurvelinear animations:^{Self.center =Self.smallCircleView.center; } completion:^ (BOOL finished) {Self.smallCircleView.hidden =NO; }]; }else {Uiimageview *imageview = [[Uiimageview Alloc] initWithFrame:Self.bounds]; [Self Addsubview:imageview];Nsmutablearray *images = [Nsmutablearray array];for (int i =1; I <=8; i++) {NSString *imagename = [NSString stringWithFormat:@ "%d", I];UIImage *image = [UIImage Imagenamed:imagename]; [Images Addobject:image]; } imageview.animationimages = images; Imageview.animationduration =0.6; Imageview.animationrepeatcount =1; [ImageView startanimating]; Dispatch_after (Dispatch_time (Dispatch_time_now, (int64_t) (0.5 *NSEC_PER_SEC)), Dispatch_get_main_queue (), ^{[Self Removefromsuperview]; }); } }}- (CGFloat) Distancewithpointa: (Cgpoint) Pointa POINTB: (Cgpoint) pointb{CGFloat dx = pointb.x-pointa.x;CGFloat dy = pointb.y-pointa.y;return sqrt (DX * dx + dy * dy);} - (Uibezierpath *) Pathwithbigcircleview: (UIView *) Bigcircleview Smallcircleview: (UIView *) smallcircleview{Cgpoint bigcenter = Bigcircleview.center;CGFloat x2 = bigcenter.x;CGFloat y2 = bigcenter.y;CGFloat r2 = bigCircleView.bounds.size.width/2;Cgpoint smallcenter = Smallcircleview.center;CGFloat x1 = smallcenter.x;CGFloat y1 = smallcenter.y;CGFloat r1 = smallCircleView.bounds.size.width/2;Get Center DistanceCGFloat d = [Self Distancewithpointa:bigcenter pointb:smallcenter];Θ: (Xita)CGFloat sinθ= (X2-X1)/D;CGFloat cosθ= (y2-y1)/D;coordinate system based on parent controlCgpoint Pointa =Cgpointmake (X1-R1 * cosθ, y1 + r1 * sinθθ);Cgpoint POINTB =Cgpointmake (x1 + r1 * cosθ, Y1-R1 * sinθθ);Cgpoint POINTC =Cgpointmake (x2 + r2 * cosθ, Y2-R2 * sinθθ);Cgpoint Pointd =Cgpointmake (X2-R2 * cosθ, y2 + r2 * sinθθ);Cgpoint Pointo =cgpointmake (pointa.x + d/2 * sinθθ, pointa.y + d/2 * cosθ); cgpoint pointp = cgpointmake (pointb.x + d/2 * sinθθ, pointb.y + d/2 * cosθ); uibezierpath *path = [uibezierpath BezierPath]; //A [path Movetopoint:pointa]; //AB [path ADDLINETOPOINT:POINTB]; //plot BC curve [path ADDQUADCURVETOPOINT:POINTC CONTROLPOINT:POINTP]; //CD [path ADDLINETOPOINT:POINTD]; //draw da Curve [path Addquadcurvetopoint:pointa controlpoint:pointo]; return Path;}  @end             

iOS development QQ Sticky animation effect

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.