Original: Swift: Creating a slide-unlock text animation
Recent wood things, find out to play with the paper Facebook. Everywhere is the "slide to unlock your phone" effect ah. Glitter glitter a little bit cool feeling. So I'm going to look into it. The thought of the wood is incredibly can be used Cagradientlayer and a small animation can achieve this effect. "Swipe to unlock" effect:
Of course, first you need to show this "sliding unlock" text. Here we will use a simple uilabel to solve this problem.
var textexamplelabel:uilabel! Override func viewdidload () { super.viewdidload () = UILabel (Frame:cgrectmake ( ) "slide to unlock your phone, slide to unlockyour"
c15> Self.view.addSubview (Textexamplelabel) }
label as a member variable (property) that is initialized in the viewdidload method and assigned to the "Sliding unlock" text.
After that, use the gradient layer to mask the text. Let's see how to prepare this mask. To use Calayer this east, must not be less than the preconditions need to introduce Quartzcore.
Import Quartzcore
Later, in order to meet the subsequent gradient mask, a portion of the code needs to be refactored. Let the color of the whole background be black, so that the text of the label is white. This looks like the unlocked animation is more pronounced in a strong black-and-white contrast. After refactoring the code:
Self.view.backgroundColor =Uicolor.blackcolor () Textexamplelabel= UILabel (Frame:cgrectmake (Ten, -, Uiscreen.mainscreen (). Bounds.size.width- -, -)) Textexamplelabel.text="slide to unlock your phones, slide to unlock yo"Textexamplelabel.backgroundcolor= Uicolor.blackcolor ()//background Color-BlackTextexamplelabel.textcolor = Uicolor.whitecolor ()//foreground color -WhiteSelf.view.addSubview (Textexamplelabel)
These are all in the Viewdidload method.
Now add Mask:
var gradientmask = cagradientlayer () let colors:array<AnyObject> = [ Uicolor.blackcolor (). Cgcolor, Uicolor.whitecolor (). Cgcolor, Uicolor.blackcolor (). Cgcolor] = colors = Gradientmask
After running out, you will be startled. Because, all is black ...
This is because the Mask property needs to use a transparent portion of the color. In other words, the color of a given change needs to appear partially transparent or translucent, so that the gradient layer can function as a mask of another layer. Another problem that needs to be noticed is that the above Gradientmask also needs to have a frame. This value is typically the bounds of the view where the Mask property is located. Do not use the wrong frame, so gradientmask mask to the wrong place. After the completion of the code, the following:
varTestgradient =Cagradientlayer ()Testgradient.frame =self.textExampleLabel.bounds testgradient.colors= [Uicolor (white:1.0, Alpha:0.3). Cgcolor, Uicolor.yellowcolor (). Cgcolor, Uicolor (white:1.0, Alpha:0.3). Cgcolor] Testgradient.startpoint= Cgpointmake (0,0.5) Testgradient.endpoint= Cgpointmake (1,0.5) Testgradient.locations= [0,0.15,0.3]
The start point and end points are represented in the coordinate system of the layer, respectively. The x and Y are not used in the general positioning frame. For example, when (0.5,0.5) represents the center of the layer, center point. (0,0.5) represents the midpoint of a layer's wound along which corresponds to (0,0.5) the midpoint of the lower edge. The start point and end point here are the midpoint of the left and right edges, respectively. The dividing line of the final gradient is perpendicular to this. This is also a very important rule.
The locations of the gradient layer is used to specify the end position of each color. Here are 0,0.15 and 0.3 respectively. These points can be interpreted as a percentage distribution along the line of color gradients, that is, start point and end point. However, the last bit of effect is not. So, the last color continues to the end of the gradient layer.
Here you can see clearly that the color change is from Uicolor (white:1.0, alpha:0.3). Cgcolor until white and all that remains is Uicolor (white:1.0, alpha:0.3). Cgcolor.
Here, we should get this effect to move. How can you try animation without moving?!
First make up the one that just missed out:
Self.textExampleLabel.layer.mask = Testgradient
The way you add animations is easier. Used to be the ancient core animation:cabasicanimation. This animation is the locations attribute that works on the gradient layer. So the initialization of this animation should be this:
var " Locations ")
Then, this animation is from one locations to another locations. Just like the unlock screen of the iphone we see, the highlighted text, from beginning to end, repeats over and over again. Until the screen dims.
varTestanimation = Cabasicanimation (keypath:"Locations") Testanimation.fromvalue= [0,0.15,0.3] Testanimation.tovalue= [1-0.3,1-0.15,1.0]; Testanimation.repeatcount=10000testanimation.duration=0.3testanimation.Delegate= Self
Here we set the color gradient from 0 to 0.15, then to 0.3. This is the beginning, then the last what should be, is the length of 0.3 of the length of three colors, so is from 1.0-0.3, and then to 1.0-0.15 last to 1.0. The missing in the middle is automatically mended by the animation.
OK, let the animation work:
" TEST ")
You only need to add an animation that has just been initialized and configured for the layer. Layer animation will begin to work. As for the value of Forkey can be very casual, do not give anything can also. Run the code and you'll see the effect of the animation.
But if you look closely at this seemingly perfect animation, you will find it. The text effect that is highlighted with white does not work on the first few letters. And at the end, the white highlight doesn't appear on the last few words. So, at this point, we'll use the coordinate system of the layer we talked about earlier. The x values for start point and end are all set on 0 and 1. That means the gray will appear on 0 to 0.15. At the end of the animation, the gray will appear on 1.0-0.15 to 1.0. Therefore, you need to move the starting X value forward and move the last X value backwards. That is, the starting x value becomes negative, and the last X value should be 1.0 + a value. So, here we set the start point and end point respectively to:
Testgradient.startpoint = Cgpointmake (-0.30.5) = Cgpointmake (10.3 0.5)
At this point, run this animation. Well, everything is perfect ...
But... But what if there are many places in the app that have this effect? Are we going to use this code in the simplest and most straightforward way? This is very elementary and very shameful behavior, but also to bury themselves a time bomb. If you need to change the gradient color, and so on, you forget to change the code somewhere ...
We are going to refactor this code so that we can use this effect in any place and use the function code that we refactored to make it very simple.
Add a new Swift file. Abstract our "sliding unlock" animation feature in this file:
The new class here is inherited from NSObject, because we just need to function at a later time to add the UIView property, and it does not need to be a subclass of UIView.
What do we need in this class? A UIView subclass that can set mask. Mask's gradient layer's translucent color (when there is a highlight) and the highlighted color (white). How many times this animation will continue to be repeated, how long each time it takes to execute ... In a word, it's basically these things. So take a look at our definition:
varAnimationview:uiview?varnothighlightcolor:uicolor!varhighlightcolor:uicolor!varCurrentanimation:cabasicanimation?varEffectwidth:cgfloat =20.0 //width of the gradient colors would take effectLet repeatcount:float=10000000 //Here , we'll let the animation repeat like foreverLet Animationduration:cftimeinterval =0.5Let Ktextanimationkey="textanimation"
Out of the main thing we said above, is the member variables of some animations and the key value of the animation. Delete the corresponding animation when the animation stops executing, rather than deleting any other animations that might be added to the layer.
Start the animation:
Override init () { 1.00.3) = uicolor.whitecolor () }
Initializes a non-highlighted color and a highlighted color at initialization time.
How to start the animation:
func Start () {ifSelf.animationview = =Nil {print ("animtion View is nil!") return } //clear things used last timeself.stop ()varGradientmask =Cagradientlayer () gradientmask.frame= self.animationview!. BoundsvarGradientsize = Self.effectwidth/cgrectgetwidth (self.animationview!. Frame)varstartlocations:array<anyobject> = [0, Gradientsize/2.0, Gradientsize]varendlocations:array<anyobject> = [1.0-Gradientsize,1.0-(Gradientsize/2.0),1.0] varColors:array<anyobject> =[Self.notHighlightColor.CGColor, Self.highlightColor.CGColor, Self.notHighlightColor.CGColor] gradientmask.co Lors=Colors Gradientmask.locations=startlocations Gradientmask.startpoint= Cgpointmake (-gradientsize,0.5) Gradientmask.endpoint= Cgpointmake (1+ Gradientsize,0.5) Self.animationview!. Layer.mask =Gradientmask self.currentanimation= Cabasicanimation (keypath:"Locations") Self.currentanimation!. Fromvalue =startlocations self.currentanimation!. Tovalue =endlocations self.currentanimation!. RepeatCount =Self.repeatcount self.currentanimation!. Duration =self.animationduration self.currentanimation!.Delegate=Self gradientmask.addanimation (self.currentanimation, Forkey:ktextanimationkey)}
In the method, it is first judged whether the UIView subclass of animation is present and returns immediately if it does not exist. If it exists, then the code for the main function we have just refactored is all put here to perform the animation. What's changed here is that the area of the gradient color can be specified in the program, not just at the beginning of the hard code we get. It is important to note that in programming, it is best not to show hard code. The worst case scenario also needs to be set to a constant attribute. The hard code code left behind in the codes will almost certainly produce bug!
Here's a look at the stop method called in the Start method. The main thing is to be clear about the related things in the last animation execution. Avoid interference.
func Stop () { if self.animationview! = Nil && self.animationview?. Layer.mask! = Nil { self.animationview?. Layer.mask.removeAnimationForKey (Ktextanimationkey) Self.animationview? Layer.mask = Nil = nil } }
This is a clear layer of mask and the animation on the mask.
Finally is the proxy method animationdidstop (anim: caanimation!, finished flag: Bool ) . Executing this method indicates that the animation has stopped. We can also execute our stop method here.
override func animationdidstop (anim:caanimation!, finished Flag:bool) { if Anim = = self.currentanimation { self.stop () } }
After the refactoring is complete, see how it should be used. We expose the calling interface to other code, as mentioned earlier. Perform the UIView subclasses of this animation, and the length of the gradient:
Self.view.backgroundColor =Uicolor.blackcolor () Textexamplelabel= UILabel (Frame:cgrectmake (Ten, -, Uiscreen.mainscreen (). Bounds.size.width- -, -)) Textexamplelabel.text="slide to unlock your phones, slide to unlock yo"Textexamplelabel.backgroundcolor= Uicolor.blackcolor ()//background Color-BlackTextexamplelabel.textcolor = Uicolor.whitecolor ()//foreground color -WhiteSelf.view.addSubview (Textexamplelabel) self.textanimation=textanimation () Self.textAnimation.animationView=Textexamplelabel self.textAnimation.effectWidth=50.0
Then perform the animation after the view appear:
Self.textAnimation.start ()
OK, now look at the entire code after the refactoring:
Import Uikitimport QuartzcoreclassViewcontroller:uiviewcontroller {vartextexamplelabel:uilabel!vartextanimation:textanimation!Overridefunc viewdidload () {super.viewdidload () Self.view.backgroundColor=Uicolor.blackcolor () Textexamplelabel= UILabel (Frame:cgrectmake (Ten, -, Uiscreen.mainscreen (). Bounds.size.width- -, -)) Textexamplelabel.text="slide to unlock your phones, slide to unlock yo"Textexamplelabel.backgroundcolor= Uicolor.blackcolor ()//background Color-BlackTextexamplelabel.textcolor = Uicolor.whitecolor ()//foreground color -WhiteSelf.view.addSubview (Textexamplelabel) self.textanimation=textanimation () Self.textAnimation.animationView=Textexamplelabel self.textAnimation.effectWidth=50.0 } Overridefunc viewdidappear (animated:bool) {super.viewdidappear (animated) Self.textAnimation.start () } Overridefunc didreceivememorywarning () {super.didreceivememorywarning ()//Dispose of any resources the can be recreated. }}
Complete the full text!
Reference: Https://github.com/jonathantribouharet/JTSlideShadowAnimation
Swift: Create a slide-unlock text animation