(8/18)重學Standford_iOS7開發_協議、block、動畫_課程筆記

第八課:html

  一、協議git

    另外一種安全處理id類型的方式如:id <MyProtocol> objgithub

    a.聲明segmentfault

//協議通常放於.h文件中或者在類的.h文件中

@protocol Foo <Xyzzy, NSObject>//<>中的內容表示還需實現自哪些協議,全部協議的根協議通常都是NSObject
- (void)someMethod;//默認爲必須實現的方法
@optional//可選方法聲明
- (void)methodWithArgument:(BOOL)argument;
@required
@property (readonly) int readonlyProperty; //只有getter在協議中
@property NSString *readwriteProperty; //getter與setter都在協議中
 - (int)methodThatReturnsSomething;
@end

    b.在類中實現協議安全

#import 「Foo.h」 
@interface MyClass : NSObject <Foo> 
//(do not have to declare Foo’s methods again here, it’s implicit that you implement it)
@end

//或者私有實現
@interface MyClass() <Foo>
@end
@implementation MyClass
//@required methods here! 
@end

    c.用途多線程

      ①委託框架

      ②數據源dom

//UI與controller盲通訊的方式
@property (nonatomic, weak) id <UISomeObjectDelegate> delegate;
@property (nonatomic, weak) id <UISomeObjectDataSource> dataSource;

      ③動畫async

  二、Block(來源於API文檔)ide

    實際上爲一段代碼塊,相似於C語言中的函數指針

    a.聲明

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
    return num * multiplier;
};
//int 爲block返回值 
//^表示爲此爲代碼塊
//myBlock爲此代碼塊名
//int 爲參數類型
//等號右邊爲block實現

    block可使用和他的同一範圍內聲明的變量,使用block與使用C函數相似

int multiplier = 7;
int (^myBlock)(int) = ^(int num) {
    return num * multiplier;
};
 
printf("%d", myBlock(3));
// prints "21"

    b.直接使用block

      block能夠省略block聲明直接使用

char *myCharacters[3] = { "TomJohn", "George", "Charles Condomine" };

//直接使用block做爲參數 
qsort_b(myCharacters, 3, sizeof(char *), ^(const void *l, const void *r) {
    char *left = *(char **)l;
    char *right = *(char **)r;
    return strncmp(left, right, 1);
});
 
// myCharacters is now { "Charles Condomine", "George", "TomJohn" } 

    c.Cocoa中使用block

NSArray *stringsArray = @[ @"string 1",
                           @"String 21",
                           @"string 12",
                           @"String 11",
                           @"String 02" ];
 
static NSStringCompareOptions comparisonOptions = NSCaseInsensitiveSearch | NSNumericSearch |
        NSWidthInsensitiveSearch | NSForcedOrderingSearch;
NSLocale *currentLocale = [NSLocale currentLocale];
 
//比較器爲代碼塊
NSComparator finderSortBlock = ^(id string1, id string2) {
    NSRange string1Range = NSMakeRange(0, [string1 length]);
    return [string1 compare:string2 options:comparisonOptions range:string1Range locale:currentLocale];
};
 
NSArray *finderSortArray = [stringsArray sortedArrayUsingComparator:finderSortBlock];
NSLog(@"finderSortArray: %@", finderSortArray);
 
/*
Output:
finderSortArray: (
    "string 1",
    "String 02",
    "String 11",
    "string 12",
    "String 21"
)
*/

    d.__block變量

      首先看簡單的例子

//直接使用變量
int x = 123;
 
void (^printXAndY)(int) = ^(int y) {
    printf("%d %d\n", x, y);
};
 
printXAndY(456); // prints: 123 456

//不能夠直接更改變量,此處變量對block來講爲只讀
int x = 123;
void (^printXAndY)(int) = ^(int y) {
    x = x + y; // error
    printf("%d %d\n", x, y);
};

      解決方法,引入__block變量

__block int x = 123; //  x lives in block storage
 
void (^printXAndY)(int) = ^(int y) {
    x = x + y;
    printf("%d %d\n", x, y);
};
printXAndY(456); // prints: 579 456
// x is now 579

    e.各類類型的變量在block中的使用

      對於普通局部變量,在block聲明時保存其值,以後普通局部變量的改變對block不可見

//注意block的調用時機
extern NSInteger CounterGlobal;//block對全局變量有讀寫權限
static NSInteger CounterStatic;//靜態變量
{
    NSInteger localCounter = 42;//普通本地變量
    __block char localCharacter;//__block本地變量
 
    void (^aBlock)(void) = ^(void) {
        ++CounterGlobal;
        ++CounterStatic;
        CounterGlobal = localCounter; // localCounter fixed at block creation
        localCharacter = 'a'; // sets localCharacter in enclosing scope
    };
 
    ++localCounter; // unseen by the block,對block不可見,block的值認爲42
    localCharacter = 'b';
 
    aBlock(); // execute the block
    // localCharacter now 'a'
}

    f.對象在block中的使用

dispatch_async(queue, ^{
    /* 
    block中訪問實例變量,instanceVariable爲block所在類的實例變量,此時直接訪問了實例變量,所以須要對包含它的對象(self)保留
    */
    doSomethingWithObject(_instanceVariable);
});
 
 
id localVariable = _instanceVariable;
dispatch_async(queue, ^{
    /*
    在本地建立了指向實例變量的引用,所以須要保留localVariable而不是self
    */
    doSomethingWithObject(localVariable);
});

    g.使用typedef聲明block

typedef float (^MyBlockType)(float, float);
 
MyBlockType myFirstBlock = // ... ;
MyBlockType mySecondBlock = // ... ;

    h.Memory Cycles 

//block中引用self,因此有強指針指向self,而block又在self中定義,因此self又有強指針指向block
[self.myBlocks addObject:^ {
    [self doSomething];
}];

      解決方法

__weak MyClass *weakSelf = self; //從新聲明爲弱引用
[self.myBlocks addObject:^ {
    [weakSelf doSomething];
}];

    i.用途

      枚舉,動畫,排序,通知(Notification),Error handlers,Completion handlers (錯誤與完成事件的處理,能夠理解爲回調函數),多線程

  三、動畫(Animation)

    a.動畫的種類

      Animating views :視圖動畫,包括移動、縮放、淡入淡出、旋轉等

      Animation of View Controller transitions:視圖控制器動畫,視圖的切換等

      Core Animation:核心動畫框架

      本節課只涉及視圖動畫

    b.爲視圖添加動畫的三種方法

      ①經過設置視圖屬性

        frame

        transform (translation, rotation and scale)

        alpha (opacity) 

       值會當即改變,但動畫效果會延時

+ (void)animateWithDuration:(NSTimeInterval)duration
                                  delay:(NSTimeInterval)delay
                               options:(UIViewAnimationOptions)options
                          animations:(void (^)(void))animations
                          completion:(void (^)(BOOL finished))completion;//適用於常規動畫設置
//example
[UIView animateWithDuration:3.0
                      delay:0.0
                    options:UIViewAnimationOptionBeginFromCurrentState
                 animations:^{ myView.alpha = 0.0; }
                 completion:^(BOOL fin) { if (fin) [myView removeFromSuperview]; }];//視圖在3秒內從父視圖淡出,完成動畫後並移除本身

+ (void)transitionWithView:(UIView *)view
                  duration:(NSTimeInterval)duration
                   options:(UIViewAnimationOptions)options
                animations:(void (^)(void))animations
                completion:(void (^)(BOOL finished))completion;//適用於轉場動畫設置,好比卡牌的翻轉

+ (void)transitionFromView:(UIView *)fromView
                    toView:(UIView *)toView
                  duration:(NSTimeInterval)duration
                   options:(UIViewAnimationOptions)options
                completion:(void (^)(BOOL finished))completion;//適用於切換視圖動畫

 

//UIViewAnimationOptions

//常規動畫屬性設置(能夠同時選擇多個進行設置)
UIViewAnimationOptionLayoutSubviews          //父視圖變化時自動更新子視圖約束@see:http://segmentfault.com/q/1010000002872390 
UIViewAnimationOptionAllowUserInteraction      //動畫時響應用戶事件,如 touch等   
UIViewAnimationOptionBeginFromCurrentState     //從當前狀態開始動畫,好比此時有動畫正在改變屬性
UIViewAnimationOptionRepeat                    //無限制重複動畫
UIViewAnimationOptionAutoreverse               //執行動畫迴路(動畫運行到結束點後仍然以動畫方式回到初始點),前提是設置動畫無限重複
UIViewAnimationOptionOverrideInheritedDuration //忽略嵌套動畫時間設置
UIViewAnimationOptionOverrideInheritedCurve    //忽略嵌套動畫速度設置
UIViewAnimationOptionAllowAnimatedContent      //動畫過程當中重繪視圖(注意僅僅適用於轉場動畫)
UIViewAnimationOptionShowHideTransitionViews   //視圖切換時直接隱藏舊視圖、顯示新視圖,而不是將舊視圖從父視圖移除(僅僅適用於轉場動畫)
UIViewAnimationOptionOverrideInheritedOptions  //不繼承父動畫設置或動畫類型

//動畫速度控制(可從其中選擇一個設置)
UIViewAnimationOptionCurveEaseInOut           //動畫先緩慢,而後逐漸加速
UIViewAnimationOptionCurveEaseIn               //動畫逐漸變慢
UIViewAnimationOptionCurveEaseOut              //動畫逐漸加速
UIViewAnimationOptionCurveLinear              //動畫勻速執行,默認值

//轉場類型(僅適用於轉場動畫設置,能夠從中選擇一個進行設置,基本動畫、關鍵幀動畫不須要設置)
UIViewAnimationOptionTransitionNone            //沒有轉場動畫效果
UIViewAnimationOptionTransitionFlipFromLeft    //從左側翻轉效果
UIViewAnimationOptionTransitionFlipFromRight   //從右側翻轉效果
UIViewAnimationOptionTransitionCurlUp          //向後翻頁的動畫過渡效果
UIViewAnimationOptionTransitionCurlDown        //向前翻頁的動畫過渡效果
UIViewAnimationOptionTransitionCrossDissolve   //舊視圖溶解消失顯示下一個新視圖的效果
UIViewAnimationOptionTransitionFlipFromTop     //從上方翻轉效果
UIViewAnimationOptionTransitionFlipFromBottom  //從底部翻轉效果

      ②Dynamic Animator :動力動畫

        實現步驟:a.建立一個UIDynamicAnimator

             b.向UIDynamicAnimator添加UIDynamicBehaviors(gravity, collisions, etc.)

             c.向UIDynamicAnimator添加UIDynamicItems(usually UIViews) 

             d.動畫自動運行

//Create a UIDynamicAnimator
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:aView];

//Create and add UIDynamicBehaviors
UIGravityBehavior *gravity = [[UIGravityBehavior alloc] init];
 [animator addBehavior:gravity];
UICollisionBehavior *collider = [[UICollisionBehavior alloc] init];
 [animator addBehavior:collider];

//Add UIDynamicItems to a UIDynamicBehavior
id <UIDynamicItem> item1 = ...; 
id <UIDynamicItem> item2 = ...; 
[gravity addItem:item1]; 
[collider addItem:item1]; 
[gravity addItem:item2];
//UIDynamicItem 協議
@protocol UIDynamicItem
@property (readonly) CGRect bounds;
@property (readwrite) CGPoint center;
@property (readwrite) CGAffineTransform transform; 
@end

//通常UIView便可做爲Item,天生實現了UIDynamic協議

//以上屬性通常有動畫運行時的animator來改變,若須要主動改變,須要調用
- (void)updateItemUsingCurrentState:(id <UIDynamicItem>)item;

         UIDynamicBehaviors

//UIGravityBehavior
@property CGFloat angle;//重力方向,默認向下
@property CGFloat magnitude; // 1.0 is 1000 points/s/s

//UICollisionBehavior 碰撞
@property UICollisionBehaviorMode collisionMode; // Items,Boundaries,Everything (default) 
- (void)addBoundaryWithIdentifier:(NSString *)identifier forPath:(UIBezierPath *)path; //用UIBezierPath自定義碰撞邊界
@property BOOL translatesReferenceBoundsIntoBoundary;//參考視圖(動力動畫的頂級視圖)做爲碰撞邊界

//UIAttachmentBehavior 吸附行爲
- (instancetype)initWithItem:(id <UIDynamicItem>)item attachedToAnchor:(CGPoint)anchor;//以點做爲吸附
- (instancetype)initWithItem:(id <UIDynamicItem>)i1 attachedToItem:(id <UIDynamicItem>)i2;//以動力項做爲吸附,兩個動力項的吸附
- (instancetype)initWithItem:(id <UIDynamicItem>)item offsetFromCenter:(CGPoint)offset ... //偏移中心的吸附
@property (readwrite) CGFloat length; // 吸附的長度
@property (readwrite) CGPoint anchorPoint; // 吸附點
@property (readwrite, nonatomic) CGFloat damping; // 錨點移動時的阻尼
@property (readwrite, nonatomic) CGFloat frequency; // 錨點移動時的頻率

//UISnapBehavior 捕捉行爲
- (instancetype)initWithItem:(id <UIDynamicItem>)item snapToPoint:(CGPoint)point;
 @property CGFloat damping;.//移動到錨點時振動的阻尼

//UIPushBehavior 推進行爲
@property UIPushBehaviorMode mode; // Continuous or Instantaneous
@property CGVector pushDirection;
@property CGFloat magnitude/angle; // magnitude 1.0 moves a 100x100 view at 100 pts/s/s

//UIDynamicItemBehavior 動力項行爲,應用於全部Items
@property (readwrite, nonatomic) CGFloat elasticity; // 彈力,[0.1]
@property (readwrite, nonatomic) CGFloat friction; //摩擦力,0表示無摩擦力
@property (readwrite, nonatomic) CGFloat density; // 密度,默認爲1
@property (readwrite, nonatomic) CGFloat resistance; //線性阻力系數0--CGFLOAT_MAX
@property (readwrite, nonatomic) CGFloat angularResistance; //角度阻力系數0--CGFLOAT_MAX
@property (readwrite, nonatomic) BOOL allowsRotation; //是否容許旋轉
- (CGPoint)linearVelocityForItem:(id <UIDynamicItem>)item;//獲取Item速度
- (CGFloat)angularVelocityForItem:(id <UIDynamicItem>)item;//獲取Item角速度

         建立UIDynamicBehavior子類實現自定義行爲

- (void)addChildBehavior:(UIDynamicBehavior *)behavior;//將其餘行爲添加到自定義行爲中
@property UIDynamicAnimator *dynamicAnimator;//獲取當前行爲所在的Animator
- (void)willMoveToAnimator:(UIDynamicAnimator *)animator;//行爲加入到方法或者移除時(此時參數爲nil)會調用
@property (copy) void (^action)(void);//每當行爲發生時總會執行此block,注意調用比較頻繁的效率問題 

  四、demo

    Dropit:https://github.com/NSLogMeng/Stanford_iOS7_Study/commit/515b76c7ed6e74a7e30108efe6d4c833f33a6e0c

 

課程視頻地址:網易公開課:http://open.163.com/movie/2014/1/D/L/M9H7S9F1H_M9H80D0DL.html

       或者iTunes U搜索standford課程

相關文章
相關標籤/搜索