ios動畫

1、動畫塊ios

frame bounds center alpha  Transition(過渡) transform(動畫效果)express

 咱們以前使用過的UIView動畫  其實本質上也是   CoreAnimation實現的,之上對它裏面的動畫進行了封裝數組

 視圖支持動畫的屬性有  frame bounds center alpha transform 以及動畫的延時 動畫的曲線(淡入淡出,動畫過渡) 重複次數緩存

 + (void)setAnimationDelegate:(id)delegate;併發

 + (void)setAnimationWillStartSelector:(SEL)selector   當動畫即將開始時,執行delegate對象的selector,而且把beginAnimations:context:中傳入的參數傳進selectorapp

 + (void)setAnimationDidStopSelector:(SEL)selector  當動畫結束時,執行delegate對象的selector,而且把beginAnimations:context:中傳入的參數傳進selector框架

 

 + (void)setAnimationDuration:(NSTimeInterval)duration   動畫的持續時間,秒爲單位ide

 

 + (void)setAnimationDelay:(NSTimeInterval)delay  動畫延遲delay秒後再開始函數

 

 + (void)setAnimationStartDate:(NSDate *)startDate   動畫的開始時間,默認爲now性能

 

 + (void)setAnimationCurve:(UIViewAnimationCurve)curve  動畫的節奏控制

 

 + (void)setAnimationRepeatCount:(float)repeatCount  動畫的重複次數

 

 + (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses  若是設置爲YES,表明動畫每次重複執行的效果會跟上一次相反

 

 + (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache  設置視圖view的過渡效果, transition指定過渡類型, cache設置YES表明使用視圖緩存,性能較好

//    開始動畫

    [UIView beginAnimations:@"ll" context:nil];

//    設置動畫持續時間

    [UIView setAnimationDuration:3];

//    具體的動畫效果

    imageView.alpha = 0.5;

    [UIView setAnimationDuration:3];

    imageView.alpha = 1;

//    設置bounds

    imageView.bounds = CGRectMake(0, 0, 100, 100);

    imageView.center = CGPointMake(50, 300);

//    提交動畫

    [UIView commitAnimations];

過渡動畫

typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {

     UIViewAnimationTransitionNone,

     UIViewAnimationTransitionFlipFromLeft, 從左面翻轉

     UIViewAnimationTransitionFlipFromRight,從右面翻轉

     UIViewAnimationTransitionCurlUp, 向上翻頁

     UIViewAnimationTransitionCurlDown,向下翻頁

     };

過渡狀態

typedef NS_ENUM(NSInteger, UIViewAnimationCurve) {

     UIViewAnimationCurveEaseInOut,         // slow at beginning and end  慢進慢出

     UIViewAnimationCurveEaseIn,            // slow at beginning  快進

     UIViewAnimationCurveEaseOut,           // slow at end  快出

     UIViewAnimationCurveLinear   勻速

     };

 

還原視圖的初始狀態

[UIView animateWithDuration:3 animations:^{

        imageView.transform = CGAffineTransformIdentity;

    }];

2、圖層

CoreAnimation   核心動畫 須要導入  QuartCore 框架 (如今不須要)

 CALayer(圖層)UIView 的關係:

 UIView中有一個layer屬性的做爲根視圖層,根圖層沒有隱式動畫,根視圖上能夠放其餘子圖層,在UIView中全部可以看到的內容都包含在layer

 CALayer 負責視圖中的顯示的內容和動畫

 UIView 負責監聽和響應事件

 CALayer 的存在乎義正在:

 IOSCALayer的設計主要是爲了內容展和動畫操做、CALayer自己並不包含在UIKit中。他不能響應事件

 

 CALayer的經常使用屬性:

 定義一個圖層位置

 bounds:圖層的大小

 position:圖層的中心點

 anchorPoint 錨點、定位點 錨點的描述是相對於 本身的*x *y位置比例而言的 默認在圖像中心點(0.50.5)的位置 決定圖層的那個點  顯示在中心點位置 

 contents 圖層顯示內容,例如能夠將圖片做爲圖層內容顯示 

 contentsRect 圖層顯示內容的大小和位置 

 

 cornerRadius 圓角半徑

 doubleSided 圖層背面是否顯示,默認爲YES

 frame 圖層大小和位置,不支持隱式動畫,因此CALayer中不多使用frame,一般使用boundsposition代替

 hidden 是否隱藏

 mask 圖層蒙版

 maskToBounds 子圖層是否剪切圖層邊界,默認爲NO

 opacity 透明度 ,相似於UIViewalpha

 position 決定圖層在父視圖的位置 圖層位於 *父視圖* 中心點位置,相似於UIViewcenter

 shadowColor 陰影顏色

 shadowOffset 陰影偏移量

 shadowOpacity 陰影透明度,注意默認爲0,若是設置陰影必須設置此屬性

 shadowPath 陰影的形狀

 shadowRadius 陰影模糊半徑

 sublayers 子圖層

 sublayerTransform 子圖層形變

 transform 圖層形變

 寫「是」的都支持隱式動畫

 以上支持隱式動畫的屬性 本質是這些屬性的變更默認隱含了CABasicAnimation動畫實現

- (void)test1

{

    //    CALayerUIView的關係:

    //    UIView中有一個layer屬性做爲根圖層,根圖層上能夠放其餘子圖層,在UIView中全部可以看到的內容都包含在layer

    //    CALayer負責視圖中顯示的內容和動畫

    //    UIView負責監聽和響應事件

    

    UIView *view = [[UIView alloc]initWithFrame:CGRectMake(100, 100, 100, 100)];

    view.backgroundColor = [UIColor redColor];

    

    [self.view addSubview:view];

    

    //    圖層上不能夠添加監聽和響應事件

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(testResponse:)];

    [view addGestureRecognizer:tap];

}

- (void)testResponse:(UITapGestureRecognizer *)sender{

    

    sender.view.layer.cornerRadius = sender.view.layer.cornerRadius == 0 ? 50 : 0;

}

#pragma mark -----------CALayer初體驗---------------

- (void)layerTest1{

    myLayer = [[CALayer alloc]init];

    myLayer.bounds = CGRectMake(100, 200, 300, 300);

//    設置中心點

    myLayer.position = CGPointMake(100, 300);

    myLayer.cornerRadius = 150;

    myLayer.backgroundColor = [UIColor colorWithRed:1.000 green:0.295 blue:0.384 alpha:1.000].CGColor;

    myLayer.borderWidth = 2;

    myLayer.borderColor = [UIColor whiteColor].CGColor;

    myLayer.shadowColor = [UIColor yellowColor].CGColor;

//    設置陰影顏色 必須設置shadowOpacity 陰影顏色的透明度(默認爲徹底透明)

    myLayer.shadowOpacity = 1.0;

    myLayer.shadowOffset = CGSizeMake(-1, -1);

//    子圖層是添加到根圖層上的

    [self.view.layer addSublayer:myLayer];

    

}

點擊手勢方法

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    UITouch *touch = [touches anyObject];

    myLayer.position = [touch locationInView:self.view];

//    myLayer.backgroundColor = [UIColor yellowColor].CGColor;

    CGFloat width = CGRectGetWidth(myLayer.bounds);

    width = width == 300 ? 100:300;

    myLayer.cornerRadius = width/2;

    myLayer.bounds = CGRectMake(0, 0, width, width);

    myLayer.backgroundColor = myLayer.backgroundColor == [UIColor redColor].CGColor ? [UIColor colorWithRed:1.000 green:0.336 blue:0.378 alpha:1.000].CGColor : [UIColor redColor].CGColor;

}

3、圖層動畫

- (void)addLayer{

    myLayer = [[CALayer alloc]init];

    myLayer.backgroundColor = [UIColor colorWithRed:1.000 green:0.037 blue:0.000 alpha:1.000].CGColor;

    myLayer.shadowColor = [UIColor colorWithRed:1.000 green:0.950 blue:0.353 alpha:1.000].CGColor;

//    陰影的透明度默認爲0

    myLayer.shadowOpacity = 1.0;

    

    myLayer.bounds = CGRectMake(0, 0, width, width);

    myLayer.borderWidth = 2;

    myLayer.borderColor = [UIColor yellowColor].CGColor;

    myLayer.cornerRadius = width/2;

    myLayer.shadowRadius = width/2;

    myLayer.shadowOffset = CGSizeMake(-1, -1);

    myLayer.position = self.view.center;

//    myLayer.contents = (id)[UIImage imageNamed:@"touxiang"].CGImage;

//    myLayer.masksToBounds = YES;

    [self.view.layer addSublayer:myLayer];

}

 

- (void)addImageLayer{

    otherLayer = [[CALayer alloc]init];

    otherLayer.bounds = CGRectMake(0, 0, width, width);

    otherLayer.contents = (id)[UIImage imageNamed:@"touxiang"].CGImage;

    otherLayer.masksToBounds = YES;

    otherLayer.position = self.view.center;

    otherLayer.borderWidth = 2;

    otherLayer.borderColor =[UIColor yellowColor].CGColor;

    otherLayer.cornerRadius = width/2;

    [self.view.layer addSublayer:otherLayer];

}

 

 

 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    UITouch *touch = [touches anyObject];

    [self changeFaceWith:[touch locationInView:self.view]];

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    UITouch *touch = [touches anyObject];

    [self changeFaceWith:[touch locationInView:self.view]];

}

- (void)changeFaceWith:(CGPoint)point{

    myLayer.position = point;

    width = width == 100 ? 300 : 100;

    myLayer.bounds = CGRectMake(0, 0, width, width);

    myLayer.cornerRadius = width/2;

    otherLayer.position = point;

    otherLayer.bounds = CGRectMake(0, 0, width, width);

    otherLayer.cornerRadius= width/2;

}

4、動畫錨點

 anchorPoint 錨點 以錨點爲中心執行動畫 (與漁夫定船的效果同樣)

 anchorPoint 默認是0.5,0.5      錨點是一個比例

 anchorPoint 在左上角的時候爲 0 0

 anchorPoint 在右上角的時候爲 1 0

 anchorPoint 在左下角的時候爲 0 1

 anchorPoint 在右下角的時候爲 1 1

- (void)shipLayer{

    shipLayer = [[CALayer alloc]init];

    shipLayer.backgroundColor = [UIColor brownColor].CGColor;

    shipLayer.bounds = CGRectMake(0, 0, 100, 100);

    shipLayer.position = self.view.center;

//    CALayer 的透明度

    shipLayer.opacity = 0.5;

    [self.view.layer addSublayer:shipLayer];

    NSLog(@"錨點x==%f,錨點y==%f",shipLayer.anchorPoint.x,shipLayer.anchorPoint.y);

    

    

    APLayer = [[CALayer alloc]init];

    APLayer.backgroundColor = [UIColor redColor].CGColor;

    APLayer.bounds = CGRectMake(0, 0, 5, 5);

//    經過shipLayer設置APLayer的中心點   position.x = shipLayer的寬*錨點x  position.y = shipLayer的高*錨點y

    CGFloat x = CGRectGetWidth(shipLayer.bounds)*shipLayer.anchorPoint.x;

    CGFloat y = CGRectGetHeight(shipLayer.bounds)*shipLayer.anchorPoint.y;

//    CGFloat xScale = x/CGRectGetWidth(self.view.frame);

//    CGFloat yScale = y/CGRectGetHeight(self.view.frame);

    APLayer.position = CGPointMake( x, y);

    [shipLayer addSublayer:APLayer];

    

    

    

    

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    UITouch *touch = [touches anyObject];

    CGPoint touchPoint = [touch locationInView:self.view];

    

//    經過屏幕的x/屏幕的寬度 獲得點擊的點 與屏幕的一個比例

    CGFloat xScale = touchPoint.x/CGRectGetWidth(self.view.frame);

    CGFloat yScale = touchPoint.y/CGRectGetHeight(self.view.frame);

    shipLayer.anchorPoint = CGPointMake(xScale, yScale);

//    經過屏幕的y/屏幕的高度 獲得點擊的點 與屏幕的一個比例

    APLayer.position = CGPointMake(CGRectGetWidth(shipLayer.bounds)*shipLayer.anchorPoint.x, CGRectGetHeight(shipLayer.bounds)*shipLayer.anchorPoint.y);

    NSLog(@"錨點x==%f,錨點y==%f",shipLayer.anchorPoint.x,shipLayer.anchorPoint.y);

//    角度值經計算轉化爲弧度值   要把角度值轉化爲弧度值   以使用一個簡單的公式Mπ/180;

    shipLayer.transform = CATransform3DMakeRotation(45*M_PI/180, 0, 0, 1);//x y z是三個軸 0(不旋轉) 1(爲旋轉)

    

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

    shipLayer.transform = CATransform3DIdentity;

}

5、核心動畫

ios中分的核心動畫爲幾類:基礎動畫(CABasicAnimation) 關鍵幀動畫(CAKeyframeAnimation) 動畫組(CAAnimationGroup) 轉場動畫 (CATransition)

    CAAnimation :核心動畫的基礎類,不能直接使用,負責動畫運行時間、速度的控制、自己實現了CAMediaTiming協議

    關鍵幀動畫和基礎動畫的區別:基礎動畫只能從一個點到另外一個點,關鍵幀動畫能夠設置多個點,從第一個點依次到最後一個點

    CAPropertyAnimation 屬性動畫也是基類(經過屬性進行動畫設置,注意是動畫屬性),不能直接使用。

    CABasicAnimation:基礎動畫,經過屬性修改進行動畫參數控制,只有初始狀態和結束狀態。

    CAKeyframeAnimation:關鍵幀動畫,一樣是經過屬性進行動畫參數控制,可是同基礎動畫不一樣的是它能夠有多個狀態控制。

    CAAnimationGroup:動畫組,動畫組是一種組合模式設計,能夠經過動畫組來進行全部動畫行爲的統一控制,組中全部動畫效果能夠併發執行。

    CATransition:轉場動畫,主要經過濾鏡進行動畫效果設置。

    基礎動畫、關鍵幀動畫都屬於屬性動畫,就是經過修改屬性值產生動畫效果,開發人員只須要設置初始值和結束值,中間的過程動畫(又叫補間動畫)由系統自動計算產生,和基礎動畫不一樣的是關鍵幀動畫能夠設置多個屬性值,每兩個屬性中間的補間動畫由系統自動完成,所以從這個角度而言基礎動畫又能夠當作是有兩個關鍵幀的關鍵幀動畫

    建立基礎動畫 須要經過fromValuetoValue 屬性來指定一個開始值和結束值 當添加基礎動畫到圖層中的時候,他纔會開始變化

    autoreverses:當設定這個屬性爲YES時,在他到達目的地以後,會以動畫的方式返回到開始值

    duration 設定開始值到結束值花費的時間 期間會被速度的屬性影響

     speed 默認的值爲 1.0.這意味着動畫播放按照默認的速度。若是你改變這個值爲 2.0,動畫會用 2 倍的速度播放。 這樣的影響就是使持續時間減半。若是你指定的持續時間爲 6 ,速度爲 2.0,動畫就會播放 3 秒鐘---一半的 持續時間

     把速度設置成0 就能夠暫停動畫

 repeatCount 默認的是 0,意味着動畫只會播放一次  這個不該該和 repeatDration 屬性一塊使用。(負數不是無限循環)

 repeatDuration 這個屬性指定了動畫應該被重複多久。動畫會一直重複,直到設定的時間流逝完。它不該該和 repeatCount 一塊兒使用

 

 timingFunction 速度控制函數,控制動畫運行的節奏

 timingFunction 屬性值:

 kCAMediaTimingFunctionLinear(線性):勻速,給你一個相對靜態的感受

 kCAMediaTimingFunctionEaseIn(漸進):動畫緩慢進入,而後加速離開

 kCAMediaTimingFunctionEaseOut(漸出):動畫全速進入,而後減速的到達目的地

 kCAMediaTimingFunctionEaseInEaseOut(漸進漸出):動畫緩慢的進入,中間加速,而後減速的到達目的地。這個是默認的動畫行爲。

 removedOnCompletion 默認爲YES,表明動畫執行完畢後就從圖層上移除,圖形會恢復到動畫執行前的狀態。若是想讓圖層保持顯示動畫執行後的狀態,那就設置爲NO,不過還要設置fillModekCAFillModeForwards

 

 fillMode  設置當前對象在非活動時間段的行爲 好比動畫開始以前或者動畫結束以後

 fillMode屬性值(上面提到過 要想fillMode有效,須要設置removedOnCompletion = NO

 

 kCAFillModeRemoved 這個是默認值,也就是說當動畫開始前和動畫結束後,動畫對layer都沒有影響,動畫結束後,layer會恢復到以前的狀態

 kCAFillModeForwards 當動畫結束後,layer會一直保持着動畫最後的狀態

 kCAFillModeBackwards 在動畫開始前,只須要將動畫加入了一個layerlayer便當即進入動畫的初始狀態並等待動畫開始。

 kCAFillModeBoth 這個其實就是上面兩個的合成.動畫加入後開始以前,layer便處於動畫初始狀態,動畫結束後layer保持動畫最後的狀態

6、顯式動畫

  UIImage *image = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"heart" ofType:@"jpg"]];

    showLayer = [[CALayer alloc]init];

    showLayer.bounds = CGRectMake(0, 0, image.size.width/2, image.size.width/2);

    showLayer.position = self.view.center;

    showLayer.contents = (id)image.CGImage;

    [self.view.layer addSublayer:showLayer];

#pragma mark ----- 改變基礎動畫的中心點(position------

- (void)anmiation1{

//    CABasicAnimation 屬於 屬性動畫 需告訴她 我們改變的屬性是哪一個 (把屬性當作字符串傳遞)

    CABasicAnimation *anmiation = [CABasicAnimation animationWithKeyPath:@"position"];

//    toValue  設置動畫要道哪一個位置

    anmiation.toValue = [NSValue valueWithCGPoint:CGPointMake(400, showLayer.position.y)];

    anmiation.duration = 3;//持續時間爲3

//    以動畫效果回到初始位置

    anmiation.autoreverses = YES;

//    若是使用fillModel必須禁用removedOnCompletion

//    anmiation.removedOnCompletion = NO;

//    anmiation.fillMode = kCAFillModeBoth;

//    設置 慢進慢出

    anmiation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

    

    

//    添加動畫到圖層   forKey:動畫的名字,能夠爲空

    [showLayer addAnimation:anmiation forKey:@"move"];

}

#pragma mark -------bounds --------

- (void)animation2{

    UIImage *image = [UIImage imageNamed:@"touxiang"];

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"];

    animation.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, image.size.width/1, image.size.width/1)];

    animation.duration = 0.5;

    animation.autoreverses = YES;

//    repeatCount == -1 不是無限循環  HUGE爲無窮大

    animation.repeatCount = HUGE;

    [showLayer addAnimation:animation forKey:@"jump"];

}

 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

//    [self animation2];

    [self addAnimation3];

}

 

- (void)addAnimation3{

//    基礎動畫繼承至屬性動畫 經過屬性名當作一個key來肯定圍繞哪一個屬性 進行動畫

    CABasicAnimation *animation= [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];//設置須要改變的屬性

    animation.fromValue = @(-0.07);

    animation.toValue = @(0.07);//transform.rotation.z z軸爲中心,旋轉1

    animation.duration = 0.05;

    animation.repeatCount = 2;

//    是否容許以動畫的方式返回

    animation.autoreverses = YES;

    [showLayer addAnimation:animation forKey:@"zhendon"];

}

- (void)addAnimation4{

    //    基礎動畫繼承至屬性動畫 經過屬性名當作一個key來肯定圍繞哪一個屬性 進行動畫

    CABasicAnimation *animation= [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];//設置須要改變的屬性

    animation.fromValue = @(-0.07);

    animation.toValue = @(0.07);//transform.rotation.z z軸爲中心,旋轉1

    animation.duration = 0.05;

    animation.repeatCount = 2;

    //    是否容許以動畫的方式返回

    animation.autoreverses = YES;

    [showLayer addAnimation:animation forKey:@"zhendon"];

}

 

7、關鍵幀動畫

 CAKeyframeAnimation 也屬於  CAPropertyAnimation

 關鍵幀動畫 可讓咱們精確的控制動畫效果 它的原理是把動畫序列裏面比較關鍵幀提取出來 設置他的動畫效果

 path 屬性 意爲路徑  執行動畫軌跡的路徑

 values 屬性 執行動畫軌跡的數組

UIImageView *imageView = [[UIImageView alloc]initWithFrame:[UIScreen mainScreen].bounds];

    imageView.image = [UIImage imageNamed:@"hua.jpg"];

    [self.view addSubview:imageView];

    [self addPetal];

- (void)addPetal{

    UIImage *image = [UIImage imageNamed:@"huaban"];

    petalLayer = [[CALayer alloc]init];

    petalLayer.bounds = CGRectMake(0, 0, image.size.width, image.size.height);

    petalLayer.position = CGPointMake(150, 250);

    petalLayer.contents = (id)image.CGImage;

    [self.view.layer addSublayer:petalLayer];

    

}

 

- (void)dropAnimation{

    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];

//    animation.fromValue = [NSValue valueWithCGPoint:petalLayer.position];

    animation.toValue = [NSValue valueWithCGPoint:CGPointMake(300, 500)];

    animation.duration = 5;//持續5

    animation.removedOnCompletion = NO;//禁用

    animation.fillMode = kCAFillModeBoth;

    [petalLayer addAnimation:animation forKey:@"drop"];

    

}

 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    [self dropAnimation];

}

8、核心動畫1

- (void)addHeart{

    UIImage *image = [UIImage imageNamed:@"heart.jpg"];

    heartLayer = [[CALayer alloc]init];

    heartLayer.bounds = CGRectMake(0, 0, image.size.width/4, image.size.height/4);

    heartLayer.position = CGPointMake(self.view.center.x, 200);

    heartLayer.contents = (id)image.CGImage;

    [self.view.layer addSublayer:heartLayer];

    

    

}

- (void)petalDrop{

    CAKeyframeAnimation *drop = [CAKeyframeAnimation animationWithKeyPath:@"position"];

    drop.duration = 5;

//    drop.values = @[[self getPointWithX:50 andY:100],[self getPointWithX:60 andY:110],[self getPointWithX:70 andY:130],[self getPointWithX:80 andY:140]];

//    建立路徑

    CGMutablePathRef path = CGPathCreateMutable();

//    給路徑添加一個起始點

    CGPathMoveToPoint(path, NULL, petalLayer.position.x, petalLayer.position.y);

//    有起始點 能夠經過起始點到另外一個點畫線

    CGPathAddLineToPoint(path, NULL, petalLayer.position.x+100, petalLayer.position.y+10);

    CGPathAddLineToPoint(path, NULL, petalLayer.position.x-100, petalLayer.position.y+30);

//    關閉路徑

//    CGPathCloseSubpath(path);

    

    drop.path = path;

//  釋放路徑

    CGPathRelease(path);

    path = nil;

    drop.removedOnCompletion = NO;

    drop.fillMode = kCAFillModeBoth;

    [petalLayer addAnimation:drop forKey:@"drop1"];

}

 

- (void)addAnimation{

//   CAKeyframeAnimation 關鍵幀動畫

    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];

    animation.duration = 1;

    animation.repeatCount = 1;//HUGE

    NSMutableArray *array = [NSMutableArray array];

    for (float t=2*M_PI; t > 0; t=t-0.1) {

//經過心形曲線得到 心形曲線上的點

        [array addObject: [self getPointWithX:40*(2*cos(t)-cos(2*t)) andY:35*(2*sin(t)-sin(2*t))]];

    }

//畫一個心形曲線

    animation.values = [array copy];

 

    [heartLayer addAnimation:animation forKey:@"move"];

    

}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    [self addAnimation];

    [self petalDrop];

}

- (void)addPetal

{

    UIImage *petal = [UIImage imageNamed:@"huaban"];

    

    petalLayer = [[CALayer alloc]init];

    petalLayer.bounds = CGRectMake(0, 0, petal.size.width, petal.size.height);

    petalLayer.position = CGPointMake(100, 200);

    petalLayer.contents = (id)petal.CGImage;

    [self.view.layer addSublayer:petalLayer];

}

#pragma mark CGPoint轉換成NSValue

- (NSValue *)getPointWithX:(CGFloat)x andY:(CGFloat)y{

    return [NSValue valueWithCGPoint:CGPointMake(x+heartLayer.position.x, y+heartLayer.position.y)];

}

9、動力效果

 UIDynamic是從iOS7開始引入的一種新技術  屬於UIKit框架 能夠模擬現實生活中的物理現象 如碰撞 抖動 擺動

    玩動力效果  如玩電吉他   電吉他有效果器  能夠添加各類電子效果

    動力效果  也有一個效果器 叫作 動力效果器  裏面能夠添加 動力效果

    

    電吉他切換效果  會把上一個效果移除

    動力效果 也是同樣

    

    電吉他能夠疊加多個效果

    動力效果 也是同樣

     

     使用UIDynamic大致步驟:

     1、建立一個動力效果器(UIDynamicAnimator)

     2、建立動力效果(Behavior)添加到對應的視圖上

     3、將動力效果添加到動力效果器中 開始動力效果

     必須遵照了UIDynamicItem這個協議纔可使用動力效果

     UIView默認已經遵照了UIDynamicItem協議

     

     UIDynamic提供的動力效果

     UIGravityBehavior:重力效果

     UICollisionBehavior:碰撞效果

     UIDynamicItemBehavior:動力元素效果

     UIPushBehavior:推進效果

     UISnapBehavior:迅速移動效果

     UIAttachmentBehavior:附着效果

     

     都繼承自UIDynamicBehavior

     

     動力效果器:UIDynamicAnimator

     能夠把UIDynamicAnimator看作動力效果的容器 它制定了動力效果的有效範圍

     在初始化的時候能夠指定他的有效範圍

     - (instancetype)initWithReferenceView:(UIView*)view;

     做用在哪個view 哪個view就是他產生動力效果的有效範圍

     

     既然是容器  他還能夠添加移除 動力效果

     - (void)addBehavior:(UIDynamicBehavior *)behavior; 添加動力效果

     - (void)removeBehavior:(UIDynamicBehavior *)behavior; 移除動力效果

     - (void)removeAllBehaviors; 移除以前添加過的全部動力效果

     

     動力效果器經常使用的屬性

     @property (nonatomic, readonly) UIView* referenceView;做用的區域

     @property (nonatomic, readonly, copy) NSArray* behaviors;添加到效果器中的全部效果

     @property (nonatomic, readonly, getter = isRunning) BOOL running;是否正在進行

     @property (nonatomic, assign) id <UIDynamicAnimatorDelegate> delegate;能夠檢測開始暫停

     - (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator;

     - (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator;

     

     Behavior 動力效果

     重力效果:UIGravityBehavior

     設置重力方向 加速度 讓物體(視圖)朝着重力方向掉落

     @property (nonatomic, readonly, copy) NSArray *items;添加到重力效果中的全部效果做用對象

     @property (readwrite, nonatomic) CGVector gravityDirection;重力方向(是一個二維向量)以左上角爲座標原點 x 負數向左 正數向右  y 負數向上  正數向下  數字越大  重力效果越大

     @property (readwrite, nonatomic) CGFloat angle;重力方向(是一個角度,x軸正方向爲,順時針正數,逆時針負數)

     @property (readwrite, nonatomic) CGFloat magnitude;量級(用來控制加速度,1.0表明加速度是1000 points /second²)重力加速度越大 碰撞越厲害

     

     可讓物體之間實現碰撞效果

     也能夠經過添加邊界(boundary)在邊界實現碰撞效果

     邊界相關的方法

     - (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier forPath:(UIBezierPath*)bezierPath; 添加一個貝塞爾曲線路徑的邊界

     - (void)addBoundaryWithIdentifier:(id <NSCopying>)identifier fromPoint:(CGPoint)p1 toPoint:(CGPoint)p2; 經過添加兩個點連成的線 做爲邊界

     - (UIBezierPath*)boundaryWithIdentifier:(id <NSCopying>)identifier; 經過ID找到邊界路徑

     - (void)removeBoundaryWithIdentifier:(id <NSCopying>)identifier; 移除ID對應的邊界

     @property (nonatomic, readonly, copy) NSArray* boundaryIdentifiers; 邊界數組

     - (void)removeAllBoundaries;移除全部邊界

     

     typedef NS_OPTIONS(NSUInteger, UICollisionBehaviorMode) {

     UICollisionBehaviorModeItems        = 1 << 0,元素碰撞

     UICollisionBehaviorModeBoundaries   = 1 << 1,邊界碰撞

     UICollisionBehaviorModeEverything   = NSUIntegerMax 全體碰撞

     } NS_ENUM_AVAILABLE_IOS(7_0);

     

     //兩個元素相互碰撞

     - (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p;

     - (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2;

     

     // 視圖碰撞邊界的時候 觸發

     - (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier atPoint:(CGPoint)p;

     - (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier;

     

     UIDynamicItemBehavior 動力元素效果

     能夠設置 動力效果的默認值 是一個輔助的效果 設置運動學元素參與物理效果過程當中的參數 如:彈性係數、摩擦係數、密度、阻力、角阻力以及是否容許旋轉等

     經常使用屬性

     @property (readwrite, nonatomic) CGFloat elasticity; // Usually between 0 (inelastic) and 1 (collide elastically) 屬性設置碰撞彈性係數 範圍(0.0-1.0)決定了碰撞的彈性程度,好比碰撞時物體的彈性

     @property (readwrite, nonatomic) CGFloat friction; // 0 being no friction between objects slide along each other設置摩擦係數 決定了沿接觸面滑動時的摩擦力大小

     @property (readwrite, nonatomic) CGFloat density; // 1 by default 密度   size相關 計算物體的總質量 質量越大 物體加速或減速就越困難

     @property (readwrite, nonatomic) CGFloat resistance; // 0: no velocity damping (阻力):決定線性移動的阻力大小 與摩擦係數不一樣 摩擦係數只做用於滑動運動

     @property (readwrite, nonatomic) CGFloat angularResistance; // 0: no angular velocity damping 設置角度阻力系數。(0--CGFLOAT_MAX)決定旋轉運動時的阻力大小

     @property (readwrite, nonatomic) BOOL allowsRotation; // force an item to never rotate 設置行爲中的dynamic item是否能夠旋轉  設置這個屬性爲 NO 物體就徹底不會轉動,而不管施加多大的轉動力

 

//    動力效果

    dynamicAnimator = [[UIDynamicAnimator alloc]initWithReferenceView:self.view];

//    self.view 產生動力效果的有效區域

    dynamicAnimator.delegate = self;

    view1 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];

    view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];

 

    view1.center = self.view.center;

    view1.backgroundColor = [UIColor redColor];

    [self.view addSubview:view1];

    view2.center = CGPointMake(self.view.center.x+10, self.view.center.y+10);

    view2.backgroundColor = [UIColor redColor];

    [self.view addSubview:view2];

 

#pragma mark 動力效果器代理方法

- (void)dynamicAnimatorWillResume:(UIDynamicAnimator*)animator{

    NSLog(@"啓動");

    

}

- (void)dynamicAnimatorDidPause:(UIDynamicAnimator*)animator{

    NSLog(@"暫停");

}

#pragma mark 手指觸摸屏幕時

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    UITouch *touch = [touches anyObject];

    CGPoint touchPoint = [touch locationInView:self.view];

    view1.center = touchPoint;

    

    

}

#pragma mark 重力效果

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{

//    把以前 添加過的動力效果移除

    [dynamicAnimator removeAllBehaviors];

//    View1上添加劇力效果

    UIGravityBehavior *gravity = [[UIGravityBehavior alloc]initWithItems:@[view1]];

//    設置加速度 數值越大 碰撞效果越大

    gravity.magnitude = 100;

//    設置動力效果的方向

    /*

     struct CGVector {

     CGFloat dx;   負數向左  正數向右

     CGFloat dy;   負數向上  正數向下

     };

     */

    gravity.gravityDirection = CGVectorMake(0, 1);

//    添加到效果器 開始動力效果

    [dynamicAnimator addBehavior:gravity];

    

#pragma mark 碰撞效果

//    View1上添加碰撞效果

//    UICollisionBehavior *collision = [[UICollisionBehavior alloc]initWithItems:@[view1]];

////    把動力效果器的範圍看成邊界

//    collision.translatesReferenceBoundsIntoBoundary = YES;

//    collision.collisionDelegate = self;

////    [collision addBoundaryWithIdentifier:@"line0" fromPoint:CGPointMake(280, 80) toPoint:CGPointMake(0, 300)];

////    [collision addBoundaryWithIdentifier:@"line" fromPoint:CGPointMake(0, 300) toPoint:CGPointMake(300, 600)];

//    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 200, 100, 100)];

//    [collision addBoundaryWithIdentifier:@"圓形" forPath:path];

//    [dynamicAnimator addBehavior:collision];

#pragma mark 兩個視圖之間的碰撞

    UICollisionBehavior *collision1 = [[UICollisionBehavior alloc] initWithItems:@[view1,view2]];//,view3,view4,view5,view6,view7,view8

    collision1.translatesReferenceBoundsIntoBoundary = YES;

    collision1.collisionDelegate = self;

//    collision1.collisionMode = UICollisionBehaviorModeEverything;

    [dynamicAnimator addBehavior:collision1];

#pragma mark 動力元素效果

//    能夠與其餘的動力效果配合使用

    UIDynamicItemBehavior *item = [[UIDynamicItemBehavior alloc] initWithItems:@[view1,view2]];//,view3,view4,view5,view6,view7,view8

    item.elasticity = 0.7;//設置元素的跳躍度(值的範圍0 --- 1)

    [dynamicAnimator addBehavior:item];

    

    

    

    

}

#pragma mark 與邊界碰撞

- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier atPoint:(CGPoint)p{

    NSLog(@"碰撞隔壁死亡的位置X:%f,Y:%f",p.x,p.y);

}

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item withBoundaryIdentifier:(id <NSCopying>)identifier{

//    view2.hidden = YES;

}

#pragma mark 兩個物體間相互碰撞

- (void)collisionBehavior:(UICollisionBehavior*)behavior beganContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2 atPoint:(CGPoint)p{

    NSLog(@"碰撞隔壁死亡的位置X:%f,Y:%f",p.x,p.y);

}

- (void)collisionBehavior:(UICollisionBehavior*)behavior endedContactForItem:(id <UIDynamicItem>)item1 withItem:(id <UIDynamicItem>)item2{

//    view2.hidden = YES;

}

 

10、動力效果1

UIPushBehavior  推進效果

 typedef NS_ENUM(NSInteger, UIPushBehaviorMode) {

 UIPushBehaviorModeContinuous, 持續的力

 UIPushBehaviorModeInstantaneous 瞬間的力

 } NS_ENUM_AVAILABLE_IOS(7_0);

 @property (nonatomic, readonly) UIPushBehaviorMode mode; 推進效果的樣式

 @property (nonatomic, readwrite) BOOL active; 是否激活

 @property (readwrite, nonatomic) CGFloat angle; 推進角度

 // A continuous force vector with a magnitude of 1.0, applied to a 100 point x 100 point view whose density value is 1.0, results in view acceleration of 100 points per s^2

 @property (readwrite, nonatomic) CGFloat magnitude; 推進力量

 @property (readwrite, nonatomic) CGVector pushDirection; 推進的方向

 

 

 ------------------------------

 UISnapBehavior:迅速移動效果

 // The point argument is expressed in the reference coordinate system

 - (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point;

 迅速移動效果 只能一次 添加到一個元素上  snapToPoint 讓他移動到哪個點

 

 @property (nonatomic, assign) CGFloat damping; // damping value from 0.0 to 1.0. 0.0 is the least oscillation. damping 的範圍是(0.0-1.0

 

 UIAttachmentBehavior  符着效果

 typedef NS_ENUM(NSInteger, UIAttachmentBehaviorType) {

 UIAttachmentBehaviorTypeItems, 吸附一個元素

 UIAttachmentBehaviorTypeAnchor 吸附一個點

 } NS_ENUM_AVAILABLE_IOS(7_0);

 設置吸附效果的樣式

 @property (readonly, nonatomic) UIAttachmentBehaviorType attachedBehaviorType;

 

 

 UIAttachmentBehavior:附着效果

 吸附着一個視圖 或者一個點  (也能夠多個鏈接)

 

 附着效果 一個視圖與一個錨點或者另外一個視圖相鏈接的狀況

 附着行爲描述的是兩點之間的鏈接狀況,能夠模擬剛性或者彈性鏈接

 在多個物體間設定多個UIAttachmentBehavior,能夠模擬多物體鏈接

 

 typedef NS_ENUM(NSInteger, UIAttachmentBehaviorType) {

 UIAttachmentBehaviorTypeItems, 吸附一個元素

 UIAttachmentBehaviorTypeAnchor 吸附一個點

 } NS_ENUM_AVAILABLE_IOS(7_0);

 設置吸附效果的樣式

 @property (readonly, nonatomic) UIAttachmentBehaviorType attachedBehaviorType;

 

 @property (readwrite, nonatomic) CGPoint anchorPoint;錨點

 

 @property (readwrite, nonatomic) CGFloat length;距離 與錨點的距離

 @property (readwrite, nonatomic) CGFloat damping; // 1: critical damping  跳躍度

 @property (readwrite, nonatomic) CGFloat frequency; // in Hertz   幅度

 

dynamicAnimator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];

    view = [[UIView alloc] initWithFrame:CGRectMake(50, 50,50, 50)];

    view.backgroundColor = [UIColor purpleColor];

    [self.view addSubview:view];

    view1 = [[UIView alloc] initWithFrame:CGRectMake(150, 150,50, 50)];

    view1.backgroundColor = [UIColor colorWithRed:0.300 green:0.334 blue:0.768 alpha:1.000];

    [self.view addSubview:view1];

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];

    [self.view addGestureRecognizer:tap];

 

 

- (void)tapAction:(UITapGestureRecognizer *)sender{

#pragma mark 推進效果

/*    [dynamicAnimator removeAllBehaviors];

    UIPushBehavior *push = [[UIPushBehavior alloc] initWithItems:@[view] mode:UIPushBehaviorModeContinuous];

//    x是正右  負左  y是正下  負上

    push.pushDirection = CGVectorMake(1, 0);

    push.magnitude = 5;

    push.active = YES;

    [dynamicAnimator addBehavior:push];

    ------------------------------------*/

#pragma mark 迅速移動效果

/*    [dynamicAnimator removeAllBehaviors];

    UISnapBehavior *snap = [[UISnapBehavior alloc] initWithItem:view snapToPoint:[sender locationInView:self.view]];

    snap.damping = 0;///阻尼值從0.01.00.0是最低的振盪

    [dynamicAnimator addBehavior:snap];

 ------------------------------------------*/

#pragma mark 吸符效果(吸符一個點)

    [dynamicAnimator removeAllBehaviors];

    UIAttachmentBehavior *attachment = [[UIAttachmentBehavior alloc] initWithItem:view offsetFromCenter:UIOffsetMake(20, 20) attachedToAnchor:[sender locationInView:self.view]];

    attachment.length = 100;

    attachment.damping = 0.5;

    attachment.frequency = 50;

    [dynamicAnimator addBehavior:attachment];

#pragma mark  吸符效果(吸符一個視圖)

//    UIAttachmentBehavior *attachment1 = [[UIAttachmentBehavior alloc] initWithItem:view offsetFromCenter:UIOffsetMake(10, 10) attachedToItem:view1 offsetFromCenter:UIOffsetMake(10, 10)];

//    attachment1.length = 100;

//    attachment1.damping = 0.5;

//    attachment1.frequency = 50;

//    [dynamicAnimator addBehavior:attachment1];

    

    UIAttachmentBehavior *attachment2 = [[UIAttachmentBehavior alloc] initWithItem:view1 attachedToItem:view];

    attachment2.damping = 0.5;

    attachment2.frequency = 50;

    [dynamicAnimator addBehavior:attachment2];

    

}

相關文章
相關標籤/搜索