First, the display effect
Second, the principle of introduction
1. Ideas
To achieve this effect, you need to know how the two coins are moving, and then achieve this sense of distance by zooming in and out of the effect. Ideas are as follows:
First, these two coins are in a certain range of relative movement, you can make a coin in a fixed range to do the left and right reciprocating movement, the other coin and it do "relative movement" can.
Second, let the coin move from left to right first to small and then back to normal, moving from right to left and then back to normal, so that the use of a sense of distance "relative motion."
2. Code
The first step is to achieve a coin in a certain range to achieve the left and right reciprocating movement, the need to fix a range, when the movement to the left edge of the movement, let it move to the side when the movement to the left to move.
Using the idea of MVC, we first create a model Xldot, add a Direction attribute to the model, and change the direction of motion by changing the model Direction properties.
typedef ns_enum (nsinteger,dotditection) { dotditectionleft =-1, dotditectionright = 1,}; @interface Xldot: uiview//move direction on both left and right @property (nonatomic,assign) dotditection direction;//font Color @property (nonatomic,strong) UIColor * TextColor; @end
First initialize a bean, put it on the left side of the container, set the direction to the right
Initialize the container that holds the beans _dotcontainer = [[UIView alloc] Initwithframe:cgrectmake (0, 0, +/-)]; _dotcontainer.center = Self.center; [Self addsubview:_dotcontainer]; Xldot *dot = [[Xldot alloc] Initwithframe:cgrectmake (0, 0, [self dotwidth],[self dotwidth]); Dot.backgroundcolor = [Uicolor redcolor]; Dot.direction = dotditectionright; [_dotcontainer Addsubview:dot];
PassCadisplaylink Implementation of the refresh work, the code is as follows
_link = [Cadisplaylink displaylinkwithtarget:self selector: @selector (Reloadview)]; [_link Addtorunloop:[nsrunloop Mainrunloop] formode:nsrunloopcommonmodes];
Refresh the code as follows, changing the direction property by moving to the left and right edges
Refresh ui-(void) reloadview{ xldot *dot1 = _dots.firstobject; Change the direction of movement, constrain the move range//move to the right margin when the if (dot1.center.x >= _dotcontainer.bounds.size.width-[self dotwidth]/2.0f) { Cgpoint Center = dot1.center; center.x = _dotcontainer.bounds.size.width-[self dotwidth]/2.0f; Dot1.center = center; Dot1.direction = Dotditectionleft; [_dotcontainer bringsubviewtofront:dot1]; } Move to the left margin when if (dot1.center.x <= [self dotwidth]/2.0f] { dot1.center = Cgpointmake ([Self dotwidth]/2.0f, DOT1.CENTER.Y); Dot1.direction = dotditectionright; [_dotcontainer sendsubviewtoback:dot1]; } Update the position of the first bean cgpoint center1 = dot1.center; center1.x + = Dot1.direction * [self speed]; Dot1.center = Center1;}
Display effect:
The second step is to move to the left before zooming back to normal, moving to the right first and then back to normal.
The code is as follows:
Show zoom in, Zoom out animation-(void) Showanimationsofdot: (xldot*) dot{ cgfloat apart = dot.center.x-_ dotcontainer.bounds.size.width/2.0f; Maximum distance cgfloat Maxappart = (_dotcontainer.bounds.size.width-[self dotwidth])/2.0f; The ratio of moving distance and maximum distance cgfloat appartscale = Apart/maxappart; Gets the Y-value of the proportional cosine curve cgfloat transfomscale = cos (appartscale * m_pi/2.0); Move to the right then the middle becomes larger both sides become smaller if (dot.direction = = dotditectionleft) { dot.transform = Cgaffinetransformmakescale (1 + transfomscale/4.0f, 1 + transfomscale/4.0f); Move to the left then the middle becomes smaller and the sides become larger }else if (dot.direction = = dotditectionright) { dot.transform = Cgaffinetransformmakescale ( 1-transfomscale/4.0f,1-transfomscale/4.0f);} }
The principle is to use the cosine function curve-Π/2 to Π/2Get bigger and get smaller .The characteristics
The effect is as follows:
The third step is to place another bean, and the first bean to do "relative movement", including zooming in and out of the direction of movement;
Code to guarantee the relative distance:
CGFloat apart = dot1.center.x-_dotcontainer.bounds.size.width/2.0f; Cgpoint center2 = dot2.center; center2.x = _dotcontainer.bounds.size.width/2.0f-apart; Dot2.center = Center2;
The effect is as follows:
Slightly polished:
Third, the Code
GitHub Address
IOS Imitation Weibo client red envelope loading interface xldotloading