基本屬性方法
@interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusItem, CALayerDelegate>
@property(class, nonatomic, readonly) Class layerClass; // 預設是[CALayer class],過載這個方法,可以返回自定義的LayerClass.
//init方法
- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
//NSCoding協議,例項化從序列化
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
// 預設YES,設定NO是使用者事件(觸控鍵)被忽略和從事件佇列中刪除
@property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteractionEnabled;
// 標記tag,預設=0
@property(nonatomic) NSInteger tag;
// 返回view的layer(非空)
@property(nonatomic,readonly,strong) CALayer *layer;
// 可成為焦點,預設為no
@property(nonatomic,readonly) BOOL canBecomeFocused NS_AVAILABLE_IOS(9_0);
// 是否是焦點
@property (readonly, nonatomic, getter=isFocused) BOOL focused NS_AVAILABLE_IOS(9_0);
複製程式碼
佈局Geometry
@interface UIView(UIViewGeometry)
// 當前檢視的邊界,包括大小和原點,這裡是在父檢視的座標系下
@property(nonatomic) CGRect frame;
// 當前檢視的邊界,包括大小和原點,這裡是在自己的座標系下
@property(nonatomic) CGRect bounds;
// 當前檢視的中心,並制定是在父檢視的座標系下
@property(nonatomic) CGPoint center;
// 形變屬性(平移/縮放/旋轉)--預設是CGAffineTransformIdentity。可以做成動畫
/*
CGAffineTransform結構體,有六個值,分別是:
CGFloat a, b, c, d;
CGFloat tx, ty;
*/
@property(nonatomic) CGAffineTransform transform;
// 應用到當前檢視的比例Scale
@property(nonatomic) CGFloat contentScaleFactor NS_AVAILABLE_IOS(4_0);
// 是否支援多點觸控,預設是NO
@property(nonatomic,getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled ;
// 決定當前檢視是否是處理觸控事件的唯一物件,預設為NO
@property(nonatomic,getter=isExclusiveTouch) BOOL exclusiveTouch ;
//點選鏈的處理判斷方法
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;
// 這個函式的用處是判斷當前的點選或者觸控事件的點是否在當前的View中
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;
// 把本檢視(呼叫者)下的point(第一引數)轉換為指定View(第二引數)的point(返回值)
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;
// 把指定View(第二引數)下的point(第一引數)轉化為本檢視(呼叫者)的point(返回值)
- (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;
// 把本檢視(呼叫者)下的rect(第一引數)轉換為指定View(第二引數)的rect(返回值)
- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
// 把指定View(第二引數)下的rect(第一引數)轉化為本檢視(呼叫者)的rect(返回值)
- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
// 這個屬性是決定當檢視大小邊界發生改變時,其子檢視是否也跟著自動調整大小,預設為YES
@property(nonatomic) BOOL autoresizesSubviews;
// 決定當當前檢視的父檢視大小發生變化時,當前檢視該怎麼調整自己的size
@property(nonatomic) UIViewAutoresizing autoresizingMask;
//UIViewAutoresizing列舉值:
/*
UIViewAutoresizingNone //檢視將不進行自動尺寸調整。
UIViewAutoresizingFlexibleHeight //檢視的高度將和父檢視的高度一起成比例變化。否則,檢視的高度將保持不變
UIViewAutoresizingFlexibleWidth //檢視的寬度將和父檢視的寬度一起成比例變化。否則,檢視的寬度將保持不變
UIViewAutoresizingFlexibleLeftMargin //檢視的左邊界將隨著父檢視寬度的變化而按比例進行調整。否則,檢視和其父檢視的左邊界的相對位置將保持不變。
UIViewAutoresizingFlexibleRightMargin //檢視的右邊界將隨著父檢視寬度的變化而按比例進行調整。否則,檢視和其父檢視的右邊界的相對位置將保持不變。
UIViewAutoresizingFlexibleBottomMargin //檢視的底邊界將隨著父檢視高度的變化而按比例進行調整。否則,檢視和其父檢視的底邊界的相對位置將保持不變。
UIViewAutoresizingFlexibleTopMargin //檢視的上邊界將隨著父檢視高度的變化而按比例進行調整。否則,檢視和其父檢視的上邊界的相對位置將保持不變。
*/
//// 返回最符合其子檢視的大小。返回最佳尺寸,預設返回self.frame.size
- (CGSize)sizeThatFits:(CGSize)size;
//移動並調整子檢視的大小,先呼叫sizeThatFits:,然後設定view.size
- (void)sizeToFit;
@end
複製程式碼
層次結構 UIView(UIViewHierarchy)
@interface UIView(UIViewHierarchy)
// 獲取父檢視,只讀屬性
@property(nullable, nonatomic,readonly) UIView *superview;
// 當前檢視的所有子檢視,只讀屬性
@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *subviews;
// 當前檢視上的UIWindow物件,只讀屬性
@property(nullable, nonatomic,readonly) UIWindow *window;
// 從父檢視移除
- (void)removeFromSuperview;
// 在索引位置插入一個檢視
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
// 用索引值交換兩個檢視
- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;
// 向當前檢視上新增子檢視
- (void)addSubview:(UIView *)view;
// 在某個檢視下插入一個檢視
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
// 在某個檢視上插入一個檢視
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;
// 把這個View放到最前面
- (void)bringSubviewToFront:(UIView *)view;
// 把這個View放到最後面
- (void)sendSubviewToBack:(UIView *)view;
// 告訴檢視新增子檢視
- (void)didAddSubview:(UIView *)subview;
// 即將移除子檢視
- (void)willRemoveSubview:(UIView *)subview;
// 在一個子檢視將要被新增到另一個檢視的時候傳送此訊息
- (void)willMoveToSuperview:(nullable UIView *)newSuperview;
// 已經移除,父檢視改變
- (void)didMoveToSuperview;
// 在一個檢視(或者它的超檢視)將要被新增到window的時候傳送
- (void)willMoveToWindow:(nullable UIWindow *)newWindow;
// 已經語出窗體物件
- (void)didMoveToWindow;
// 判定一個檢視是否在其父檢視的檢視層中(系統自動呼叫)
- (BOOL)isDescendantOfView:(UIView *)view;
// 返回指定tag的View
- (nullable __kindof UIView *)viewWithTag:(NSInteger)tag;
#pragma mark - 佈局
// 標記檢視需要重新佈局,會呼叫layoutSubviews
- (void)setNeedsLayout;
// 當呼叫了setNeedsLayout並不會馬上呼叫layoutSubViews,這時會呼叫該方法,可以強制發生重新佈局
- (void)layoutIfNeeded;
#pragma mark - 系統自動呼叫(留給子類去實現)
/**
* 控制元件的frame,約束髮生改變的時候就會呼叫,一般在這裡重寫佈局子控制元件的位置和尺寸
* 重寫了這個方法後一定要呼叫[super layoutSubviews]
*/
- (void)layoutSubviews; // 對子檢視佈局
/*
layoutSubviews在以下情況下會被呼叫:
1、init初始化不會觸發layoutSubviews , 但 initWithFrame 進行初始化時,當rect的值不為CGRectZero時,也會觸發.
2、addSubview會觸發layoutSubviews.
3、設定view的Frame會觸發layoutSubviews,當然前提是frame的值設定前後發生了變化.
4、滾動一個UIScrollView會觸發layoutSubviews.
5、旋轉Screen會觸發父UIView上的layoutSubviews事件.
6、改變一個UIView大小的時候也會觸發父UIView上的layoutSubviews事件.
[1]、layoutSubviews對subviews重新佈局
[2]、layoutSubviews方法呼叫先於drawRect
[3]、setNeedsLayout在receiver標上一個需要被重新佈局的標記,在系統runloop的下一個週期自動呼叫layoutSubviews
[4]、layoutIfNeeded方法如其名,UIKit會判斷該receiver是否需要layout
[5]、layoutIfNeeded遍歷的不是superview鏈,應該是subviews鏈
*/
// 佈局檢視,距離父檢視的上左下右的距離
@property (nonatomic) UIEdgeInsets layoutMargins;
// 這個屬性預設是NO,如果把它設為YES,layoutMargins會根據螢幕中相關View的佈局而改變
@property (nonatomic) BOOL preservesSuperviewLayoutMargins;
// 在我們改變View的layoutMargins這個屬性時,會觸發這個方法。我們在自己的View裡面可以重寫這個方法來捕獲layoutMargins的變化。在大多數情況下,我們可以在這個方法裡觸發drawing和layout的Update
- (void)layoutMarginsDidChange;
// 相對於View Layout Margins建立的約束,在其view的邊緣會留下一些空白的距離
@property(readonly,strong) UILayoutGuide *layoutMarginsGuide NS_AVAILABLE_IOS(9_0);
// 會根據size class來調整大小,這樣會在邊緣新增空白的距離,來跟適合閱讀
@property (nonatomic, readonly, strong) UILayoutGuide *readableContentGuide NS_AVAILABLE_IOS(9_0);
//UILayoutGuide類定義了可以通過自動佈局互動的矩形區域。使用佈局指南來替換可能已建立的虛擬檢視,以在使用者介面中表示檢視間間距或封裝
//UILayoutGuide可以虛擬View幫助的事情都可以交給UILayoutGuide來做。它更輕量、更快速、更高效。UILayoutGuide並沒有真正的建立一個View,只是建立了一個矩形空間,只在進行auto layout時參與進來計算
@end
複製程式碼
繪製--UIView(UIViewRendering)
@interface UIView(UIViewRendering)
/**
* drawRect是對receiver的重繪
* setNeedDisplay在receiver標上一個需要被重新繪圖的標記,在下一個draw週期自動重繪,iphone device的重新整理頻率是60hz,也就是1/60秒後重繪
*/
// 渲染 重寫此方法 執行重繪
- (void)drawRect:(CGRect)rect;
// 需要重新渲染 標記為需要重繪 一步呼叫drawRect
- (void)setNeedsDisplay;
// 需要重新渲染某一塊區域
- (void)setNeedsDisplayInRect:(CGRect)rect;
// 決定了子檢視的顯示範圍。具體來說,當取值為YES時,裁剪超出父檢視範圍的子檢視範圍
@property(nonatomic) BOOL clipsToBounds;
// 設定背景顏色
@property(nullable, nonatomic,copy) UIColor *backgroundColor;
// 透明度,0.0-1.0的數值,0為全透明,1為不透明
@property(nonatomic) CGFloat alpha;
// 是否透明,預設為YES==不透明
@property(nonatomic,getter=isOpaque) BOOL opaque;
/*
決定該訊息接收者(UIView instance)是否讓其檢視不透明,用處在於給繪圖系統提供一個效能優化開關。
myView.opaque = NO;
該值為YES, 那麼繪圖在繪製該檢視的時候把整個檢視當作不透明對待。優化繪圖過程並提升系統效能;為了效能方面的考量,預設被置為YES。
該值為NO,,不去做優化操作。
一個不透明檢視需要整個邊界裡面的內容都是不透明。基於這個原因,opaque設定為YES,要求對應的alpha必須為1.0。如果一個UIView例項opaque被設定為YES, 而同時它又沒有完全填充它的邊界(bounds),或者它包含了整個或部分的透明的內容檢視,那麼將會導致未知的結果。
因此,如果檢視部分或全部支援透明,那麼你必須把opaque這個值設定為NO.
*/
// 決定在子檢視重畫之前是否先清理檢視以前的內容
@property(nonatomic) BOOL clearsContextBeforeDrawing;
// 是否隱藏,預設為NO
@property(nonatomic,getter=isHidden) BOOL hidden;
// 決定當檢視邊界變時呈現檢視
@property(nonatomic) UIViewContentMode contentMode;
//設定圖片的顯示方式
typedef NS_ENUM(NSInteger, UIViewContentMode) {
UIViewContentModeScaleToFill, // 填充 根據檢視的比例去拉伸圖片內容
UIViewContentModeScaleAspectFit, // 縮放填充 保持圖片內容的縱橫比例,來適應檢視的大小
UIViewContentModeScaleAspectFill, // 用圖片內容來填充檢視的大小,多餘的部分可以被修剪掉來填充整個檢視邊界
UIViewContentModeRedraw, // 重繪邊界 這個選項是單檢視的尺寸位置發生變化的時候通過呼叫setNeedsDisplay方法來重新顯示
UIViewContentModeCenter, // 保持圖片原比例,居中
UIViewContentModeTop, // 保持圖片原比例,居上
UIViewContentModeBottom, // 保持圖片原比例,居下
UIViewContentModeLeft, // 保持圖片原比例,居左
UIViewContentModeRight, // 保持圖片原比例,居右
UIViewContentModeTopLeft, // 保持圖片原比例,居左上
UIViewContentModeTopRight, // 保持圖片原比例,居右上
UIViewContentModeBottomLeft, // 保持圖片原比例,居左下
UIViewContentModeBottomRight, // 保持圖片原比例,居右下
};
// 用於制定那部分是可拉伸的,取值在0.0~1.0之間
@property(nonatomic) CGRect contentStretch;
/*
[imageView setContentStretch:CGRectMake(150.0/300.0, 100.0/200.0, 10.0/300.0, 10.0/200.0)];
image.png的大小是 200 x 150 ;
mageView的frame是(0,0,300,200);
150.0/300.0表示x軸上,前150個畫素不進行拉伸。
100.0/200.0表示y軸上,前100個畫素不進行拉伸。
10.0/300.0表示x軸上150後的10個畫素(151-160)進行拉伸,直到image.png鋪滿imageView。
10.0/200.0表示y軸上100後的10個畫素(101-110)進行拉伸,直到image.png鋪滿imageView。
*/
@property(nullable, nonatomic,strong) UIView *maskView; // 模具檢視
@property(null_resettable, nonatomic, strong) UIColor *tintColor; // 檢視控制元件的顏色
@property(nonatomic) UIViewTintAdjustmentMode tintAdjustmentMode; // 檢視的色彩模式
/*
列舉值:
UIViewTintAdjustmentModeAutomatic, //自動的
UIViewTintAdjustmentModeNormal, //正常的
UIViewTintAdjustmentModeDimmed, //暗淡的
*/
- (void)tintColorDidChange; // 檢視顏色屬性發生變化時,由系統呼叫
@end
複製程式碼
手勢-- UIView (UIViewGestureRecognizers)
@interface UIView (UIViewGestureRecognizers)
@property(nullable, nonatomic,copy) NSArray<__kindof UIGestureRecognizer *> *gestureRecognizers; // 訪問手勢集合
- (void)addGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer; // 新增手勢
- (void)removeGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer; // 移除手勢
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer; // 通過返回值決定是否識別此手勢
@end
複製程式碼
#####動畫相關--UIView(UIViewAnimationWithBlocks)
typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {
//1.常規動畫屬性設定(可以同時選擇多個進行設定)
UIViewAnimationOptionLayoutSubviews = 1 << 0,//動畫過程中保證子檢視跟隨運動
UIViewAnimationOptionAllowUserInteraction = 1 << 1, // 動畫過程中允許使用者互動
UIViewAnimationOptionBeginFromCurrentState = 1 << 2, // 所有檢視從當前狀態開始執行
UIViewAnimationOptionRepeat = 1 << 3, // 重複執行動畫
UIViewAnimationOptionAutoreverse = 1 << 4, // 如果重複,動畫執行到結束點後仍然以動畫方式回到初始點
UIViewAnimationOptionOverrideInheritedDuration = 1 << 5, // 忽略巢狀動畫時間設定
UIViewAnimationOptionOverrideInheritedCurve = 1 << 6, // 忽略巢狀動畫速度設定
UIViewAnimationOptionAllowAnimatedContent = 1 << 7, // 動畫過程中重繪檢視(注意僅僅適用於轉場動畫)
UIViewAnimationOptionShowHideTransitionViews = 1 << 8, // 檢視切換時直接隱藏舊檢視、顯示新檢視,而不是將舊檢視從父檢視移除(僅僅適用於轉場動畫)
UIViewAnimationOptionOverrideInheritedOptions = 1 << 9, // 不繼承父動畫設定或動畫型別
//2.動畫速度控制(單選)
UIViewAnimationOptionCurveEaseInOut = 0 << 16, // 開始慢-中間塊-結束慢
UIViewAnimationOptionCurveEaseIn = 1 << 16, // 開始慢-結束快
UIViewAnimationOptionCurveEaseOut = 2 << 16, // 開始快-結束慢
UIViewAnimationOptionCurveLinear = 3 << 16, // 線性
//3.轉場型別(單選)
UIViewAnimationOptionTransitionNone = 0 << 20, // 沒有轉場動畫效果
UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20, // 從左側翻轉效果
UIViewAnimationOptionTransitionFlipFromRight = 2 << 20, // 從右側翻轉效果
UIViewAnimationOptionTransitionCurlUp = 3 << 20, // 向後翻頁的動畫過渡效果
UIViewAnimationOptionTransitionCurlDown = 4 << 20, // 向前翻頁的動畫過渡效果
UIViewAnimationOptionTransitionCrossDissolve = 5 << 20, // 舊檢視溶解消失顯示下一個新檢視的效果
UIViewAnimationOptionTransitionFlipFromTop = 6 << 20, // 從上方翻轉效果
UIViewAnimationOptionTransitionFlipFromBottom = 7 << 20, // 從底部翻轉效果
};
複製程式碼
@interface UIView(UIViewAnimationWithBlocks)
/**
view的一些動畫一般使用這個就夠了
@param duration 動畫時長
@param delay 延時執行時間
@param options 動畫型別
@param animations 動畫最後的狀態block
@param completion 動畫執行完成的block
*/
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion ;
// delay = 0.0, options = 0
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion ;
// delay = 0.0, options = 0, completion = NULL
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations;
/**
Spring Animation彈簧動畫 系統操作很多這種動畫
@param dampingRatio 0.0f-1.0f,數值越小「彈簧」的振動效果越明顯
@param velocity 初始的速度,數值越大一開始移動越快
*/
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
/**
轉場動畫
@param view 需要進行轉場動畫的檢視
*/
+ (void)transitionWithView:(UIView *)view duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);
/**
轉場動畫
// 新增toView到父檢視
[fromView.superview addSubview:toView];
// 把fromView從父檢視中移除
[fromView.superview removeFromSuperview];
*/
+ (void)transitionFromView:(UIView *)fromView toView:(UIView *)toView duration:(NSTimeInterval)duration options:(UIViewAnimationOptions)options completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // toView added to fromView.superview, fromView removed from its superview
//在一組檢視上執行指定的系統動畫,並可以並行自定義的動畫
//其中parallelAnimations就是與系統動畫並行的自定義動畫--只有UISystemAnimationDelete
+ (void)performSystemAnimation:(UISystemAnimation)animation onViews:(NSArray<__kindof UIView *> *)views options:(UIViewAnimationOptions)options animations:(void (^ __nullable)(void))parallelAnimations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
複製程式碼
簡單使用
[UIView animateWithDuration:3.0 animations:^{
//直接寫最後的view狀態
} completion:^(BOOL finished) {
//動畫結束
}];
複製程式碼
關鍵幀動畫--UIView (UIViewKeyframeAnimations)
typedef NS_OPTIONS(NSUInteger, UIViewKeyframeAnimationOptions) {
UIViewKeyframeAnimationOptionLayoutSubviews = UIViewAnimationOptionLayoutSubviews,//動畫過程中保證子檢視跟隨運動
UIViewKeyframeAnimationOptionAllowUserInteraction = UIViewAnimationOptionAllowUserInteraction, // 動畫過程中允許使用者互動
UIViewKeyframeAnimationOptionBeginFromCurrentState = UIViewAnimationOptionBeginFromCurrentState, // 所有檢視從當前狀態開始執行
UIViewKeyframeAnimationOptionRepeat = UIViewAnimationOptionRepeat, // 重複執行動畫
UIViewKeyframeAnimationOptionAutoreverse = UIViewAnimationOptionAutoreverse, // 如果重複,動畫執行到結束點後仍然以動畫方式回到初始點
UIViewKeyframeAnimationOptionOverrideInheritedDuration = UIViewAnimationOptionOverrideInheritedDuration, // 忽略巢狀動畫時間設定
UIViewKeyframeAnimationOptionOverrideInheritedOptions = UIViewAnimationOptionOverrideInheritedOptions, // 不繼承父動畫設定或動畫型別
UIViewKeyframeAnimationOptionCalculationModeLinear = 0 << 10, // default線性
UIViewKeyframeAnimationOptionCalculationModeDiscrete = 1 << 10, // 離散的
UIViewKeyframeAnimationOptionCalculationModePaced = 2 << 10, // 均勻執行運算模式
UIViewKeyframeAnimationOptionCalculationModeCubic = 3 << 10, // 平滑運算模式
UIViewKeyframeAnimationOptionCalculationModeCubicPaced = 4 << 10 // 平滑均勻運算模式
};
@interface UIView (UIViewKeyframeAnimations)
/**
關鍵幀動畫
*/
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion ;
/**
add幀動畫
@param frameStartTime 倍數從0到1,假設一個動畫持續的時間是2秒,設定frameStartTime為0.5,那麼後面設定的動畫,將會在整體動畫執行1秒後開始執行
@param frameDuration 也是一個倍數,都是相對總的duration來設定
*/
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations ;
複製程式碼
簡單使用
- (void)runAnimateKeyframes {
/**
* relativeDuration 動畫在什麼時候開始
* relativeStartTime 動畫所持續的時間
*/
[UIView animateKeyframesWithDuration:6.f
delay:0.0
options:UIViewKeyframeAnimationOptionCalculationModeLinear
animations:^{
//第一個幀動畫
[UIView addKeyframeWithRelativeStartTime:0.0 // 相對於6秒所開始的時間(第0秒開始動畫)
relativeDuration:1/3.0 // 相對於6秒動畫的持續時間(動畫持續2秒)
animations:^{
self.view.backgroundColor = [UIColor redColor];
}];
//第二個幀動畫
[UIView addKeyframeWithRelativeStartTime:1/3.0 // 相對於6秒所開始的時間(第2秒開始動畫)
relativeDuration:1/3.0 // 相對於6秒動畫的持續時間(動畫持續2秒)
animations:^{
self.view.backgroundColor = [UIColor yellowColor];
}];
//第三個幀動畫
[UIView addKeyframeWithRelativeStartTime:2/3.0 // 相對於6秒所開始的時間(第4秒開始動畫)
relativeDuration:1/3.0 // 相對於6秒動畫的持續時間(動畫持續2秒)
animations:^{
self.view.backgroundColor = [UIColor greenColor]; }];
}
completion:^(BOOL finished) {
//重複,可以設定options=UIViewKeyframeAnimationOptionRepeat
[self runAnimateKeyframes];
}];
}
複製程式碼