一、協議
@optional :可選的
@requied :必須實現的
二、block 代碼塊
1、 以一個^開頭,然后是參數,然后是一個大括號,包含我們的代碼塊
1 [aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { 2 NSLog(@“value for key %@ is %@”, key, value); 3 if ([@“ENOUGH” isEqualToString:key]) { 4 *stop = YES; 5 } 6 }];
2、如果在變量前面加上一個__block,那么這個變量就會從棧中移到堆中
1 __block BOOL stoppedEarly = NO; 2 double stopValue = 53.5; 3 [aDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { 4 NSLog(@“value for key %@ is %@”, key, value); 5 if ([@“ENOUGH” isEqualToString:key] || ([value doubleValue] == stopValue)) { 6 *stop = YES; 7 stoppedEarly = YES; // this is legal now 8 } 9 }]; 10 if (stoppedEarly) NSLog(@“I stopped logging dictionary values early!”);
3、存儲循環:只要Block存在block中所有的對象,就都有一個強指針指向它們
如下:block有一個強指針指向self,同時,self也有一個強指針指向block(self.myBlock)
1 [self.myBlocks addObject:^ { 2 [self doSomething]; 3 }];
解決方法是:采用一個__weak類型,也就是弱類型,不會存儲在堆中,沒有指針指向的時候,為nil
1 __weak MyClass *weakSelf = self; //self is strong , weakSelf is weak 2 [self.myBlocks addObject:^ { 3 [weakSelf doSomething]; 4 }];
4、應用:枚舉、視圖動畫、排序、通知、錯誤處理、后台線程處理(多線程)
三、動畫
1、三種方式:fame\transform\alpha
1 + (void)animateWithDuration:(NSTimeInterval)duration 2 delay:(NSTimeInterval)delay 3 options:(UIViewAnimationOptions)options 4 animations:(void (^)(void))animations 5 completion:(void (^)(BOOL finished))completion;
例子:
1 [UIView animateWithDuration:3.0 //代表持續多久 2 delay:0.0 //等待多長時間開始執行 3 options:UIViewAnimationOptionBeginFromCurrentState //攔截:這里的選項代表從當前狀態,而不是又從頭開始計算 4 animations:^{ myView.alpha = 0.0; } //執行修改等 5 completion:^(BOOL fin) { if (fin) [myView removeFromSuperview]; }]; //bool用來判斷動畫是否執行完成
2、IOS7 新增的
(1 新建一個UIDunamicAnimator
(2 添加動力行為:例如重力、碰撞、推動等
(3 添加內容UIdynamicItems (這些item必須實現協議)
1 UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:aView];//新建一個UIDunamicAnimator 2 3 UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];//添加行為 4 [animator addBehavior:gravity]; 5 6 id <UIDynamicItem> item1 = ... ;//添加內容 7 id <UIDynamicItem> item2 = ... ; 8 [gravity addItem:item1];
[gravity addItem:item2];
如果animator正在移動但是同時要讓它旋轉,必須調用updateItmeUsingCurrentState方法,否則由於性能關系它會假設已知道當前的狀態
3、具體的行為
(1 UIGravityBehavior //重力行為:默認方向是向下
1 @property CGFloat angle //角度 2 @property CGFloat magnitude //重力大小(為1的時候代表是重力加速度)
(2 UICollisionBehavior //碰撞行為
1 @property UICollisionBehaviorMode collisionMode //動力項:例如是相互碰撞彈開或只是從邊界碰撞彈開 2 @property BOOL translatesReferenceBoundsIntoBoundary //是否為有彈性的邊界
(3 UIAttachmentBehavior //吸附行為:通過它可以將一個動力項吸附到一個固定描點或另外一個動力項上
1 //初始化不用allocation或者init,而是在初始化時指定吸附對象,比如與另一個動力項、描點或者傾斜的方式等 2 @property CGFloat length //兩個吸附項之間的距離 3 @property CGPoint anchorPoint
(4 UISnapBehavior //速甩行為:使一個動力項飛速過去某個位置,到達后可能不會馬上停止,或許會像彈簧一樣晃動
1 //初始化的時候也是通過指定飛向的point 2 -(instancetype)initWithItme:(id <UIDynamicItme> item) snapToPoint:(CGPoint)point 3
(5 UIPushBehavior //推動行為
1 @property UIPushBehaviorMode mode //持續的或者是瞬間的、猝發的 2 @property CGVector pushDirection //推動的距離 3 @property CGFloat magnitude/angle //角度或者推力大小 4
(6 UIDynamicItemBehavior //動力項行為類:對應上面所需要添加控制的一個類,可以通過它獲取速度或者其他什么東東從而來改變現狀
1 //比如說: 2 @property BOOL allowsRotation //旋轉 3 @property BOOL friction //摩擦力 4 @property BOOL elasticity //彈力、有彈性 5 @property CGFloat density //密度
//也可以通過以下方法知道你的行為是否在執行或者是由哪個動畫執行
-(void)willMoveToAnimator(UIDynamicAnimator *)animator//當行為移動到動畫中,或者被移開都會調用到
(7 UIDynamicItemBehavior的action屬性:相當於block,只要指定了動力項行為,每次遇到這個行為都會去執行
四 、demo
這個demo比較復雜,雜糅了動畫、手勢,包括重力、吸附、碰撞、摩擦、曲線、禁止旋轉等是一個綜合性比較強的例子,可以先看看里面應用到的代碼片段
1、拖曳的手勢,要注意判斷3個時機
2、點擊手勢,掉落,這里有三個要注意的,
第一個是隨機產生很的一個方塊View,隨機數的產生是從(0到我們背景UIView的寬度之間的大小-1)
第二個是我們要將我們最后一個方塊當作我們拖曳的時候的view[這在吸附里需要取控制它的]
第三個是我們要注意動畫的加入content內容,從一開始創建一個UIDunamicAnimator,然后在添加動力行為[如碰撞重力等在一個我們封裝的類里面實現],最后添加內容也就是這第三步
3、吸附行為,這里有三個要注意的點,block的使用要注意變量、循環強指針引用、吸附的當前描點是不斷變化的
4、動畫的委托遵循UIDynamicAnimatorDelegate協議
dynamicAnimatorDidPause和dynamicAnimatorWillResume分表實現動畫結束和開始的時候要做的操作
(如果沒有_animator.delegate = self;是無法執行到的)
5、這里注意的是我們封裝了一個dropitBehavior類,這個類專門用來封裝我們的行為,
諸如我們的重力(UIGravityBehavior)、碰撞(UICollisionBehavior)、動力項行為指向(摩擦密度之類的UIDynamicItemBehavior)
在這個類操作我們控制動畫的第二步,就是將這個動力行為加入到我們的動畫中
6、還有我們的曲線類 BezierPathView,在我們ViewController中操作我們的曲線類的時候,是以我們UiView作為背景的,所以需要設置view的customClass為“BezierPathView”,
具體是在我們的吸附方法中使用block構造曲線,隨着吸附的過程構造一個拖動的曲線。
這里不一一介紹,看demo演示:
demo下載地址:http://pan.baidu.com/s/1o69kfuM