iOS Metro implementation, with Windows tile effect (one)
No nonsense-upper slag map
All the friends who turn out the "blog Park" Please indicate the source: http://www.cnblogs.com/xiaobajiu/p/4084717.html
Microsoft's Metro style looks technologically sound when flattened. So I wanted to write a Metro control for iOS. For a period of time, with the appearance. My idea is that Metro and WP8 are pretty much the same, displaying information by rotating it, touching metro it will pry or suck. Click Metro to execute the event, press and hold the tile and perform other events.
Structure: The outer layer of Metro is the skeleton layer , which acts as a stop position, the internal size changes and Metro's drag and drop will not affect the external structure. Outside the skeleton is the mask layer and the content layer . The mask layer below is the metro theme color, and the content layer holds both sides of the view to show. It is important to note that the mask layer is hidden without setting a theme.
Metro structure-Big picture
So directly into the area of friends most concerned, animation. iOS animations are cheap, unlike windows, other platforms are like taking pens in pictures, and iOS is like a printer in a brush diagram. The main drawing related to iOS has quartz2d, the core animation and so on to cope with simple rotation and telescopic drawing using uiviewanimation is enough, and the code is short. The effect of rotation is as long as one line: view.layer.transform= catransform3dmakerotation (cgfloat angle, cgfloat x, cgfloat y, cgfloat z) this way, you can achieve the rotation effect. Here is a complete intercept of the tile rotation code:
/** * (private) Metro rotation animation*/- (void) revolvemetro{_isviewdleaying=NO; [UIView Animatewithduration:_turntimes[_currentviewid] Delay:0.0options:uiviewanimationoptioncurveeasein| Uiviewanimationoptionallowuserinteraction animations:^{_isanimating= YES;//Modify Animation State_container.layer.transform= catransform3dmakerotation (M_pi_2,1.0,0.0,0.0); if(!_maskingview.hidden) _maskingview.layer.transform= Catransform3dmakerotation (M_pi_2,1.0,0.0,0.0); } Completion:^(BOOL finished) {((UIView*) Self.views[_currentviewid]). hidden=YES; ((UIView*) Self.views[[self Nextindexnownextview]]). hidden=NO; [UIView Animatewithduration:_turntimes[_currentviewid] Delay:0.0Options:uiviewanimationoptioncurveeaseout animations:^{_container.layer.transform= Catransform3dmakerotation (-m_pi_4/2,1.0,0.0,0.0); if(!_maskingview.hidden) _maskingview.layer.transform= Catransform3dmakerotation (-m_pi_4/2,1.0,0.0,0.0); } Completion:^(BOOL finished) {[UIView Animatewithduration:_turntimes[_currentviewid] Delay:0.0Options:uiviewanimationoptioncurveeasein animations:^{_container.layer.transform= Catransform3dmakerotation (0,1.0,0.0,0.0); if(!_maskingview.hidden) _maskingview.layer.transform= Catransform3dmakerotation (0,1.0,0.0,0.0); } Completion:^(BOOL finished) {_isanimating= NO;//Modify Animation State }]; }]; }];}
A total of three animations are combined, and each animation can have many useful properties set through the Options option. For example, animation time curve, simply said that the animation with gradual speed, it is drawn to the axis is a variety of curves. There is a way to switch pictures in the rotation of the tiles, there are many ways to do things like I don't have a method: [view Exchangesubviewatindex:0 withsubviewatindex:1] ; This method can directly swap the position of the two sublayers of the parent layer's sub-index 0 and 1. To achieve the purpose of switching layers. I'm using the method of hiding the layer so I don't want to disturb the layer order and find a layer easily.
In addition to the Metro's rotation there is an animated effect that is the tilt of the Metro when it is touched. By observing the WP8, the farther the touch point is from the center point, the greater the force sinks. But close to the center area is a sinking effect instead of a tilt effect. You can also see that the triggering of this animation effect should be triggered when you touch the Metro. Then this animation effect can be executed in the function of -(void) Touchesbegan: (Nsset *) touches withevent: (uievent *)event .
Then there is a tedious problem that is the problem of tilt calculation. Connaught rotates with the geometric center as the axis of symmetry, and only controls the angle of rotation to calculate how many angles should be rotated based on the distance to the geometric center when a metro touches a line through the geometric center. The axis of rotation revolves around the symmetry of the last sentence, which is rotated 90 degrees through the straight line of the geometric center (touch Point and the connection of the geometric center).
You can create a struct body to represent this vector:
/* * * vector with weights */ struct metrovector{cgfloat x; CGFloat y; CGFloat Power; // };typedef
The next step is to get touch point awhen you touch Metro. A vector V1is calculated from A and center o , and the V1 rotation 90 degrees is both the axis of symmetry V2required for tilt. Simply fill in the rotation function with V2 x, Y. It is noteworthy that view.layer.transform= catransform3dmakerotation (cgfloat angle, cgfloat x, cgfloat y, cgfloat z) is the x, Y of this function , the value range of the z-value is [0.0,1.0]. About the force I'm using the length of the segment AO , which compares the distance from O to any corner of the Metro, which is half the length of the diagonal . Two divide the number by one 0~1 to measure the strength.
Calculate the code for the vector V2:
/** * (private) calculates the vector of the 3D tilt axis of the Metro when clicked * * @param view touch views * @param touchPoint One of the touch points*/-(Metrovector) Getvectorbytouchedview: (uiview*) viewinch:(cgpoint) touchpoint{metrovector vector; CGFloat width=View.frame.size.width; CGFloat height=View.frame.size.height; CGFloat Diagonal= sqrt (width* width+ height* height);//Diagonalvector.x= touchpoint.x-width/2;//vector with geometric center as Originvector.y= touchpoint.y-height/2; CGFloat Lentouchbetweencenter= sqrt (vector.x*vector.x+ vector.y* vector.y);//the distance from the touch point to the center of GeometryCGFloat max= Max (vector.x, VECTOR.Y);//take the maximum value and divide it so that the maximum value is 1.0CGFloat temp= vector.x;//swaps x, y values, one of which is reversed (indicating that the vector is rotated 90 degrees to become the axis of the layer)Vector.x=-vector.y/Max; Vector.y= temp/Max; CGFloat Len4maxpower= diagonal/2;//take the diagonal one-second as the most forceful measureVector.power= lentouchbetweencenter/Len4maxpower; returnVector;}
With the V2, you can just tilt the code.
- (void) Touchesbegan: (Nsset *) touches withevent: (Uievent *)Event{[Super Touchesbegan:touches withevent:Event]; if(self.isanimating)return;//allow to touch, not allowed to animate againCgpoint Touchpos= [(uitouch*) [Touches Anyobject] locationinview:self]; //Central AreaCgsize viewsize=self.frame.size; CGRect Centerrect= CGRectMake (viewsize.width/4, viewsize.height/4, viewsize.width/2, viewsize.height/2); if(Cgrectcontainspoint (Centerrect, Touchpos)) {//whether the animation is dropped in the center area, yes[UIView animatewithduration:macrotouchoneanimationinterval/5Delay0.0Options:uiviewanimationoptioncurveeaseout| Uiviewanimationoptionallowuserinteraction animations:^{_isanimating=YES; Self.layer.transform= Catransform3dmakescale (0.975,0.975,1.0); } Completion:^(BOOL finished) {[UIView animatewithduration:macrotouchoneanimationinterval/2Delay0.0Options:uiviewanimationoptioncurveeaseout animations:^{self.layer.transform= Catransform3dmakescale (1.0,1.0,1.0); } Completion:^(BOOL finished) {_isanimating=NO; //.. }]; }]; }Else{//Skew AnimationMetrovector vecor= [Self getvectorbytouchedview:selfinch: Touchpos]; [UIView animatewithduration:macrotouchoneanimationinterval delay:0.0Options:uiviewanimationoptioncurveeaseout| Uiviewanimationoptionallowuserinteraction animations:^{_isanimating=YES; Self.layer.transform= Catransform3dmakerotation (Randianfromangle ( -* vecor.power), vecor.x, Vecor.y,0.0);//} completion:^(BOOL finished) {[UIView animatewithduration:macrotouchoneanimationinterval/2Delay0.0Options:uiviewanimationoptioncurveeaseout animations:^{self.layer.transform= Catransform3dmakerotation (0, Vecor.x, Vecor.y,0.0); } Completion:^(BOOL finished) {_isanimating=NO; //.. }]; }]; }}
To the present, the most core animation content has been implemented. There is also the handling of touch events, and a bunch of so-called business logic and some functional implementations. I would like to introduce another blog in the next article. and the code to download, spit the kind of copy box roll and lead to 100 degrees 100 lump identical content behavior .
Please correct your friend if there is any mistake, lest fraught.
(original) iOS Metro implementation, with Windows tile effect (a)