iOS animation advanced-Cool pull-up refresh action

Source: Internet
Author: User

Mobile Access is poor, please visit my personal blog

Recently, a pull up to refresh the small wheel, as long as the following a protocol can customize their own dynamic pull-up refresh and load, I also wrote a few of the action, the following is a better implementation of the dynamic effect of the process

First up and GitHub address, there are other good dynamic effects can also be exchanged ~

Dynamic effect of the original address, on the Uimovement website to see the dynamic effect when the feeling special 6, I want to realize their own, a long time, for a number of programs finally realized, the following are the steps to achieve:

Analysis of dynamic effects

Write a dynamic effect of the first step should be careful to analyze it, each frame of it to see, find a most appropriate way to achieve it, the following is my analysis process:

    • See the curve, will certainly think CAShapeLayer and UIBezierPath this pair of partners, relative to CoreGraphics , it is simple and efficient;
    • The pull effect of the curve can be CADisplayLink combined with a reference view , a reference view for UIBezierPath a controlPoint , mobile reference view to achieve the effect of the curve pull;
    • The rebound effect of the curve is considered repeatedly after the decision to use CAKeyframeAnimation CAShapeLayer the match to use, originally intended CASpringanimation to use to achieve, but consider it is iOS9 out, and my wheel minimum support iOS8, give up with it;
    • Small ball is realized and pop-up is relatively simple, use CAShapeLayer to achieve small ball, use CABasicAnimation to achieve the movement of small ball;
    • The effect of the rotation of the outer ring of the ball, the first is CAShapeLayer to achieve the ring, and then with CABasicAnimation CAShapeLayer the control strokeEnd and transform.rotation.z always to achieve the effect of the outer ring rotation;
    • Finally is more complex is the ball and the curve of the connection between the processing, my implementation is through the process of the CADisplayLink animation in real-time to listen to the position of the ball and curve, calculate the UIBezierPath use CAShapeLayer of a precise connection between the ball and the curve part.

Well, the above is the approximate process, if you have another better way to achieve, can also be discussed together.

Draw the curve and pull the curve

We use CAShapeLayer and UIBezierPath this pair of partners to achieve the drawing of the curve, the following with a reference to show view you, the following is the main code and:

By passing theyCoordinates to draw the curve Func wave (_y: CGFloat, execute:cgfloat) {self. Execute= Execute Wavelayer. Path= Wavepath (x:0,y:y) if!isanimation {var trans = Cgaffinetransform. Identitytrans = trans. Translatedby(x:0,y:y) reference. Transform= Trans}}//calculates pathprivate func Wavepath (x: CGFloat,y: cgfloat), Cgpath {Let w = frame. WidthLet path = Uibezierpath () ify< Execute {path. Move(To:. Zero) path. AddLine(To:. Init(x: W,y:0)) path. AddLine(To:. Init(x: W,y:y)) path. AddLine(To:. Init(x:0,y:y)) path. AddLine(To:. Zero)}else {Path. Move(To:. Zero) path. AddLine(To:. Init(x: W,y:0)) path. AddLine(To:. Init(x: W,y: Execute)) path. Addquadcurve(To:. Init(x:0,y: Execute), ControlPoint:. Init(x: w/2,y:y)) path. AddLine(To:. Zero)} return path. Cgpath}
Springback Effect of Curves

The springback of the curve is CAKeyframeAnimation added to the reference, then the coordinates of the monitoring reference are used to view CADisplayLink view controlPoint Achieve the rebound effect of the curve, and the following is the main code and:

Start animation func startanimation () {isanimation = True Adddisplay () boundanimation (x:0,y: Execute)}//cakeyframeanimation animation private func boundanimation (x: CGFloat,y: cgfloat) {Let bounce = cakeyframeanimation (keypath:"TRANSFORM.TRANSLATION.Y") Bounce. Timingfunction= Camediatimingfunction (Name:kcamediatimingfunctioneasein) Bounce. Duration= Bounceduration Bounce. Values= [Reference. Frame. Origin. Y,y*0.5,y*1.2,y*0.8,y*1.1,y] Bounce. Isremovedoncompletion= True Bounce. Fillmode= Kcafillmodeforwards Bounce. Delegate= self reference. Layer. Add(Bounce, Forkey:"Return")}//Add and remove cadisplaylinkprivate func adddisplay () {displayLink = Cadisplaylink (target:self, selector:#selector (displayaction))DisplayLink?. Add(To:. Main, Formode:. Commonmodes)}private func Removedisplay () {DisplayLink?. Invalidate() DisplayLink = nil}//Cadisplaylink bound method @objc private func displayaction () {if let frame = reference. Layer. Presentation()?. Frame{Dispatchqueue. Global(). Async{Let path = self. Displaywavepath(x:0,y: Frame. Origin. Y+ referenceheight/2) Dispatchqueue. Main. Async{Self. Wavelayer. Path= path}}}}//This method gets the pathprivate func displaywavepath (x: CGFloat,y: cgfloat), Cgpath {Let w = frame. WidthLet path = Uibezierpath () path. Move(To:. Zero) path. AddLine(To:. Init(x: W,y:0)) path. AddLine(To:. Init(x: W,y: Execute)) path. Addquadcurve(To:. Init(x:0,y: Execute), ControlPoint:. Init(x: w/2,y:y)) path. AddLine(To:. Zero) Return path. Cgpath}
Animation of the outer ring

Ball and outer ring we use CAShapeLayer to draw, here is mainly about the implementation of animation, animation is mainly composed of two parts:

    • CABasicAnimationThe animation that controls the outer ring strokeEnd ;
    • CABasicAnimationControls the rotation animation of the outer ring transform.rotation.z ;
of the outer ring's animated
strokeEnd Animationouter ring transform.rotation.z rotation

Here is the key code:

Func animation () {Self. Ishidden= False Let rotate = cabasicanimation (keypath:"Transform.rotation.z") Rotate. Fromvalue=0Rotate. Tovalue= M_pi *2Rotate. Duration=1Rotate. Timingfunction= Camediatimingfunction (name:kcamediatimingfunctionlinear) rotate. RepeatCount= HUGE Rotate. Fillmode= Kcafillmodeforwards Rotate. Isremovedoncompletion= False Self. Add(Rotate, Forkey:rotate. KeyPath) strokeendanimation ()}func strokeendanimation () {Let endPoint = Cabasicanimation (keypath:"Strokeend") EndPoint. Fromvalue=0EndPoint. Tovalue=1EndPoint. Duration=1.8EndPoint. Timingfunction= Camediatimingfunction (name:kcamediatimingfunctioneaseout) endPoint. RepeatCount= HUGE EndPoint. Fillmode= Kcafillmodeforwards EndPoint. Isremovedoncompletion= False EndPoint. Delegate= SelfAdd(EndPoint, Forkey:endpoint. KeyPath)}
The ball rising and the handling at the junction

Small ball rise animation is very simple, an CABasicAnimation animation on the implementation, the main trouble is the connection at the animation implementation, my plan is in the small ball animation process through CADisplayLink real-time monitoring of the ball and reference view location, calculate the Besle curve, and then through a named linkLayer: CAShapeLayer layer to connect them , and then let them disconnect in a specific place, following the main code and:

@objc private func displayaction () {Let Offy = Balllayer. Circlelayer. Presentation()?. Frame. Origin. YLet frame1 = Balllayer. FrameLet frame2 = Wavelayer. Reference. Layer. Presentation()?. FrameIf let Offy = Offy, let frame2 = frame2 {dispatchqueue. Global(). Async{//To determine if the ball is up or down, false is on, speed is fast, get position not in time, downward need to adjust position let Isincrement = (offy-self. Previousoffy) >0Let path = Uibezierpath () Let X1 = frame1. Origin. x+ (isincrement?)4:0) Let Y1 = frame1. Origin. Y+ offy Let w1 = frame1. Size. Width-(isincrement?)8:0) Let H1 = Frame1. Size. HeightLet x2 = frame2. Origin. xLet y2 = frame2. Origin. YLet W2 = frame2. Size. WidthLet H2 = Frame2. Size. HeightLet Suby = y2-y1//y1 and y2 spacing let subscale = suby/self. Execute/2The distance to be disconnected isTenLet executesub = self. Balllayer. Circlelayer. Moveupdist+ Offy If executesub <Ten{if!isincrement {let Executesubscale = executesub/TenPath. Move(To:. Init(x: X1- the,y: Y2 + h2/2+ the)) path. AddLine(To:. Init(x: X1 + W1 + the,y: Y2 + h2/2+ the)) path. Addquadcurve(To:. Init(x: X1- the,y: Y2 + h2/2+ the), ControlPoint:. Init(x: X1 + w1/2,y: Y2 + h2/2-Self. Execute/6* Executesubscale)}}else {Path. Move(To:. Init(x: X2,y: y2 + H2)) path. AddLine(To:. Init(x: X2 + W2,y: y2 + H2)) path. Addquadcurve(To:. Init(x: X1 + W1,y: Y1 + h1/2), ControlPoint:. Init(x: X1 + w1-w1*2*subscale,y: Y1 + (Y2-Y1)/2+ h1/2+ h2/2)) path. AddLine(To:. Init(x: x1,y: Y1 + h1/2)) path. Addquadcurve(To:. Init(x: X2,y: y2 + H2), ControlPoint:. Init(x: X1 + w1*2*subscale,y: Y1 + (Y2-Y1)/2+ h1/2+ h2/2) if Y1 + h1 <= Self. Execute, isincrement {Dispatchqueue. Main. Async{Self. Wavelayer. Startdownanimation()}}} Dispatchqueue. Main. Async{Self. Linklayer. Path= Path. Cgpath} Self. Previousoffy= Offy}}}

I think this place is not very good treatment, but the simple and rough solve the problem, if you have better suggestions, you can put forward, we exchange learning ~

Complete code, you can go to GitHub address to download, welcome to star and comments and contribution code, there are good dynamic words can also provide, finally thank you for reading

iOS animation advanced-Cool pull-up refresh action

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.