UIView 基本動(dòng)畫
// 通過指定動(dòng)畫持續(xù)時(shí)間征炼、動(dòng)畫延遲逃糟、執(zhí)行動(dòng)畫選項(xiàng)和動(dòng)畫完成后回調(diào)的 Block 對象 更改一個(gè)或多個(gè)視圖的動(dòng)畫吼鱼。
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0, completion = NULL
示例:平移動(dòng)畫
- (void)viewDidLoad {
[super viewDidLoad];
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(22, 22, 100, 100)];
view1.backgroundColor = [UIColor flatMintColor];
[self.view addSubview:view1];
[UIView animateWithDuration:2.0 // 動(dòng)畫持續(xù)時(shí)間
delay:1.0 // 動(dòng)畫執(zhí)行的延遲時(shí)間
options:UIViewAnimationOptionLayoutSubviews // 執(zhí)行的動(dòng)畫選項(xiàng)
animations:^{
// 要執(zhí)行的動(dòng)畫代碼
view1.center = self.view.center;
}
completion:^(BOOL finished) {
// 動(dòng)畫執(zhí)行完畢后的調(diào)用
}];
}
示例:重復(fù)動(dòng)畫
- (void)viewDidLoad {
[super viewDidLoad];
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(22, 22, 100, 100)];
view1.backgroundColor = [UIColor flatMintColor];
[self.view addSubview:view1];
[UIView animateWithDuration:3.0
delay:1.0
options:UIViewAnimationOptionRepeat |
UIViewAnimationOptionAutoreverse |
UIViewAnimationOptionCurveEaseInOut
animations:^{
// 要執(zhí)行的動(dòng)畫代碼
view1.center = self.view.center;
view1.backgroundColor = [UIColor flatSkyBlueColor];
}
completion:^(BOOL finished) {
// 動(dòng)畫執(zhí)行完畢后的調(diào)用
}];
}
示例:旋轉(zhuǎn)動(dòng)畫
[UIView animateWithDuration:0.25 animations:^{
cell.arrow.transform = CGAffineTransformMakeRotation(M_PI);
} completion:^(BOOL finished) {
}];
示例:嵌套動(dòng)畫
- (void)showMessage:(NSString *)msg {
CGFloat padding = 10;
YYLabel *label = [YYLabel new];
label.text = msg;
label.font = [UIFont systemFontOfSize:16];
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor colorWithRed:0.033 green:0.685 blue:0.978 alpha:0.730];
label.textContainerInset = UIEdgeInsetsMake(padding, padding, padding, padding);
label.width = self.view.width;
label.height = [msg heightForFont:label.font width:label.width] + 2 * padding;
label.bottom = (kiOS7Later ? 64 : 0);
[self.view addSubview:label];
// 顯示label動(dòng)畫
[UIView animateWithDuration:0.3 animations:^{
label.top = (kiOS7Later ? 64 : 0);
} completion:^(BOOL finished) {
// 嵌套動(dòng)畫蓬豁,2秒后隱藏label動(dòng)畫
[UIView animateWithDuration:0.2 delay:2 options:UIViewAnimationOptionCurveEaseInOut animations:^{
label.bottom = (kiOS7Later ? 64 : 0);
} completion:^(BOOL finished) {
[label removeFromSuperview];
}];
}];
}
Spring 動(dòng)畫
/* Performs `animations` using a timing curve described by the motion of a spring. When `dampingRatio` is 1, the animation will smoothly decelerate to its final model values without oscillating. Damping ratios less than 1 will oscillate more and more before coming to a complete stop. You can use the initial spring velocity to specify how fast the object at the end of the simulated spring was moving before it was attached. It's a unit coordinate system, where 1 is defined as travelling the total animation distance in a second. So if you're changing an object's position by 200pt in this animation, and you want the animation to behave as if the object was moving at 100pt/s before the animation started, you'd pass 0.5. You'll typically want to pass 0 for the velocity.
大意:使用彈簧運(yùn)動(dòng)描述的時(shí)序曲線執(zhí)行動(dòng)畫。當(dāng) dampingRatio (阻尼比)為1時(shí)菇肃,動(dòng)畫將平穩(wěn)減速到其最終模型沒有振蕩庆尘。小于1的阻尼比在達(dá)到完全停止之前會(huì)越來越波動(dòng)。你可以使用初始的彈簧速度來指定模擬彈簧在到達(dá)終點(diǎn)之前移動(dòng)的速度有多快巷送。velocity(動(dòng)畫速率)是一個(gè)單位坐標(biāo)系,其中1定義為在一秒鐘內(nèi)移動(dòng)總動(dòng)畫距離矛辕。所以在動(dòng)畫執(zhí)行過程中,如果你想改變對象的移動(dòng)距離為200pt笑跛,并且你想要?jiǎng)赢嫳憩F(xiàn)得像物體一樣 以100pt / s 的速度運(yùn)動(dòng),那么你應(yīng)該設(shè)置彈簧的速率為0.5聊品。你通常想通過0的速度飞蹂。*/
+ (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);
兩個(gè)額外參數(shù):
-
dampingRatio
:彈簧動(dòng)畫中的阻尼比。相當(dāng)于彈簧的硬度翻屈,數(shù)值在 0.0 到 1.0 之間陈哑,數(shù)值越小,彈簧越軟伸眶,波動(dòng)幅度越大惊窖;反之相反。 -
velocity
:彈簧的速率厘贼。數(shù)值越小界酒,動(dòng)力越小,彈簧的拉伸幅度就越小嘴秸。反之相反毁欣。比如:總共的動(dòng)畫運(yùn)行距離是200 points,你希望每秒 100pt 岳掐,值為 0.5凭疮;
示例
- (void)viewDidLoad {
[super viewDidLoad];
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(self.view.frame.size.width / 2 - 50, 22, 100, 100)];
view1.backgroundColor = [UIColor flatMintColor];
[self.view addSubview:view1];
[UIView animateWithDuration:3.0
delay:1.0
usingSpringWithDamping:0.4 // 彈簧阻尼比
initialSpringVelocity:0.3 // 速度
options:UIViewAnimationOptionLayoutSubviews
animations:^{
view1.center = self.view.center;
}
completion:^(BOOL finished) {
}];
}
Transitions 轉(zhuǎn)場動(dòng)畫
常用于添加、刪除子視圖或隱藏串述、顯示子視圖時(shí)的動(dòng)畫执解。
/** 為指定的容器視圖創(chuàng)建轉(zhuǎn)換動(dòng)畫 */
+ (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);
/** 使用給定的參數(shù)在指定視圖之間創(chuàng)建轉(zhuǎn)換動(dòng)畫 */
+ (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
示例一:
#pragma mark - Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.containerView];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[UIView transitionWithView:self.containerView
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromLeft |
UIViewAnimationOptionRepeat |
UIViewAnimationOptionAutoreverse
animations:^{
[self.containerView addSubview:self.subView];
}
completion:^(BOOL finished) {
}];
}
#pragma mark - Custom Accessors
- (UIView *)containerView {
if (!_containerView) {
_containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 250, 250)];
_containerView.center = self.view.center;
}
return _containerView;
}
- (UIView *)subView {
if (!_subView) {
_subView = [[UIView alloc] initWithFrame:self.containerView.bounds];
_subView.backgroundColor = [UIColor flatGreenColor];
}
return _subView;
}
示例二:
#pragma mark - Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.view1];
[self.view addSubview:self.button];
}
#pragma mark - Custom Accessors
- (UIView *)view1 {
if (!_view1) {
_view1 = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height - 450, [UIScreen mainScreen].bounds.size.width, 450)];
_view1.backgroundColor = [UIColor flatWatermelonColor];
}
return _view1;
}
- (UIView *)view2 {
if (!_view2) {
_view2 = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height - 450, [UIScreen mainScreen].bounds.size.width, 450)];
_view2.backgroundColor = [UIColor flatGreenColor];
}
return _view2;
}
#pragma mark - IBActions
- (void)startAnimation:(id)sender {
// 轉(zhuǎn)場動(dòng)畫
[UIView transitionFromView:self.view1
toView:self.view2
duration:0.25
options:UIViewAnimationOptionTransitionFlipFromRight
completion:^(BOOL finished) {
}];
}
另外,關(guān)于 UINavigationController 的 push纲酗、pop 動(dòng)畫:
天天品嘗iOS7甜點(diǎn) :: Day 10 :: Custom UIViewController Transitions
Keyframe 動(dòng)畫
/** UIView 的關(guān)鍵幀動(dòng)畫 */
@interface UIView (UIViewKeyframeAnimations)
/** 創(chuàng)建一個(gè)動(dòng)畫塊對象材鹦,可用于為當(dāng)前視圖設(shè)置基于關(guān)鍵幀的動(dòng)畫 */
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
/** 添加指定開始時(shí)間、持續(xù)時(shí)間的關(guān)鍵幀動(dòng)畫(起始和持續(xù)時(shí)間是0.0和1.0之間的值) */
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0); // start time and duration are values between 0.0 and 1.0 specifying time and duration relative to the overall time of the keyframe animation
// 開始時(shí)間和持續(xù)時(shí)間是相對于關(guān)鍵幀動(dòng)畫的總時(shí)間的位于0和1之間的值
@end
示例一:
#pragma mark - Lifecycle
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.view1];
[UIView animateKeyframesWithDuration:4.0
delay:1.0
options:UIViewKeyframeAnimationOptionRepeat
animations:^{
[UIView addKeyframeWithRelativeStartTime:0.0
relativeDuration:0.25
animations:^{
self.view1.frame = CGRectMake(50, 250, 100, 100);
}];
[UIView addKeyframeWithRelativeStartTime:0.25
relativeDuration:0.25
animations:^{
self.view1.frame = CGRectMake(250, 250, 100, 100);
}];
[UIView addKeyframeWithRelativeStartTime:0.5
relativeDuration:0.25
animations:^{
self.view1.frame = CGRectMake(250, 50, 100, 100);
}];
[UIView addKeyframeWithRelativeStartTime:0.75
relativeDuration:0.25
animations:^{
self.view1.frame = CGRectMake(50, 50, 100, 100);
}];
}
completion:^(BOOL finished) {
}];
}
#pragma mark - Custom Accessors
- (UIView *)view1 {
if (!_view1) {
_view1 = [[UIView alloc] initWithFrame:CGRectMake(50, 50, 100, 100)];
_view1.backgroundColor = [UIColor flatWatermelonColor];
}
return _view1;
}
關(guān)鍵幀動(dòng)畫的其他示例:
天天品嘗iOS7甜點(diǎn) :: Day 11 :: UIView Key-frame Animations
Layer 動(dòng)畫
示例一:CABasicAnimation
CABasicAnimation *basicAnimation = [CABasicAnimation animationWithKeyPath:@"position.x"];
basicAnimation.fromValue = @10;
basicAnimation.toValue = @200;
basicAnimation.duration = 2.0;
// 在動(dòng)畫執(zhí)行過程中保留最后一幀
basicAnimation.fillMode = kCAFillModeForwards;
basicAnimation.removedOnCompletion = NO;
[self.view1.layer addAnimation:basicAnimation forKey:nil];
示例二:CAKeyframeAnimation
UILabel 的跑馬燈效果:
摘自:Wonderful
- (void)moveAction {
// 以 Label 的中心點(diǎn)運(yùn)動(dòng)
// 貝塞爾曲線 起點(diǎn)
CGPoint fromPoint = CGPointMake(self.frame.size.width + self.marqueeLbl.frame.size.width/2, self.frame.size.height/2);
// 貝塞爾曲線 終點(diǎn)
CGPoint toPoint = CGPointMake(-self.marqueeLbl.frame.size.width/2, self.frame.size.height/2);
self.marqueeLbl.center = fromPoint;
UIBezierPath *movePath = [UIBezierPath bezierPath];
[movePath moveToPoint:fromPoint];
[movePath addLineToPoint:toPoint];
// 創(chuàng)建動(dòng)畫實(shí)例
CAKeyframeAnimation *moveAnim = [CAKeyframeAnimation animationWithKeyPath:@"position"];
// 設(shè)置動(dòng)畫路徑
moveAnim.path = movePath.CGPath;
// 設(shè)置動(dòng)畫時(shí)長
moveAnim.duration = self.marqueeLbl.frame.size.width * self.speedLevel * 0.01;
// 委托協(xié)議耕姊,動(dòng)畫完成后重復(fù)該動(dòng)畫
moveAnim.delegate = self;
// 在圖層上添加動(dòng)畫
[self.marqueeLbl.layer addAnimation:moveAnim forKey:nil];
}
#pragma mark - CAAnimationDelegate
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
if (flag) {
[self moveAction];
}
}
UIView.h 源碼解析注釋
摘自:ios開發(fā) 之 UIView詳解桶唐,部分修改。
// UIView.h
// UIKit
//
// Copyright (c) 2005-2016 Apple Inc. All rights reserved.
// Created by ZengZhiming on 2017/5/22.
//
#import <Foundation/Foundation.h>
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIResponder.h>
#import <UIKit/UIInterface.h>
#import <UIKit/UIKitDefines.h>
#import <UIKit/UIAppearance.h>
#import <UIKit/UIDynamicBehavior.h>
#import <UIKit/NSLayoutConstraint.h>
#import <UIKit/UITraitCollection.h>
#import <UIKit/UIFocus.h>
NS_ASSUME_NONNULL_BEGIN
/** 動(dòng)畫的曲線枚舉 */
typedef NS_ENUM(NSInteger, UIViewAnimationCurve) {
UIViewAnimationCurveEaseInOut, //!< 慢進(jìn)慢出(默認(rèn)值).
UIViewAnimationCurveEaseIn, //!< 慢進(jìn).
UIViewAnimationCurveEaseOut, //!< 慢出.
UIViewAnimationCurveLinear, //!< 勻速.
};
/** UIView 內(nèi)容填充模式 */
typedef NS_ENUM(NSInteger, UIViewContentMode) {
UIViewContentModeScaleToFill, //!< 縮放內(nèi)容到合適比例大小.
UIViewContentModeScaleAspectFit, //!< 縮放內(nèi)容到合適的大小茉兰,邊界多余部分透明.
UIViewContentModeScaleAspectFill, //!< 縮放內(nèi)容填充到指定大小尤泽,邊界多余的部分省略.
UIViewContentModeRedraw, //!< 重繪視圖邊界 (需調(diào)用 -setNeedsDisplay).
UIViewContentModeCenter, //!< 視圖保持等比縮放.
UIViewContentModeTop, //!< 視圖頂部對齊.
UIViewContentModeBottom, //!< 視圖底部對齊.
UIViewContentModeLeft, //!< 視圖左側(cè)對齊.
UIViewContentModeRight, //!< 視圖右側(cè)對齊.
UIViewContentModeTopLeft, //!< 視圖左上角對齊.
UIViewContentModeTopRight, //!< 視圖右上角對齊.
UIViewContentModeBottomLeft, //!< 視圖左下角對齊.
UIViewContentModeBottomRight, //!< 視圖右下角對齊.
};
/** UIView 動(dòng)畫過渡效果 */
typedef NS_ENUM(NSInteger, UIViewAnimationTransition) {
UIViewAnimationTransitionNone, //!< 無效果.
UIViewAnimationTransitionFlipFromLeft, //!< 沿視圖垂直中心軸左到右移動(dòng).
UIViewAnimationTransitionFlipFromRight, //!< 沿視圖垂直中心軸右到左移動(dòng).
UIViewAnimationTransitionCurlUp, //!< 由底部向上卷起.
UIViewAnimationTransitionCurlDown, //!< 由頂部向下展開.
};
/** 自動(dòng)調(diào)整大小方式 */
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone = 0, //!< 不自動(dòng)調(diào)整.
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,//!< 自動(dòng)調(diào)整與superView左邊的距離,保證與superView右邊的距離不變.
UIViewAutoresizingFlexibleWidth = 1 << 1,//!< 自動(dòng)調(diào)整自己的寬度,保證與superView左邊和右邊的距離不變.
UIViewAutoresizingFlexibleRightMargin = 1 << 2,//!< 自動(dòng)調(diào)整與superView的右邊距離坯约,保證與superView左邊的距離不變.
UIViewAutoresizingFlexibleTopMargin = 1 << 3,//!< 自動(dòng)調(diào)整與superView頂部的距離熊咽,保證與superView底部的距離不變.
UIViewAutoresizingFlexibleHeight = 1 << 4,//!< 自動(dòng)調(diào)整自己的高度,保證與superView頂部和底部的距離不變.
UIViewAutoresizingFlexibleBottomMargin = 1 << 5 //!< 自動(dòng)調(diào)整與superView底部的距離闹丐,也就是說横殴,與superView頂部的距離不變.
};
/** UIView動(dòng)畫選項(xiàng) */
typedef NS_OPTIONS(NSUInteger, UIViewAnimationOptions) {
// ??----------------------------------------------------------------------------
// 1.常規(guī)動(dòng)畫屬性設(shè)置(可以同時(shí)選擇多個(gè)進(jìn)行設(shè)置)
UIViewAnimationOptionLayoutSubviews = 1 << 0, // 動(dòng)畫過程中保證子視圖跟隨運(yùn)動(dòng)。**提交動(dòng)畫的時(shí)候布局子控件卿拴,表示子控件將和父控件一同動(dòng)畫衫仑。**
UIViewAnimationOptionAllowUserInteraction = 1 << 1, // 動(dòng)畫過程中允許用戶交互。
UIViewAnimationOptionBeginFromCurrentState = 1 << 2, // 所有視圖從當(dāng)前狀態(tài)開始運(yùn)行,而不是從初始狀態(tài)開始運(yùn)行堕花。
UIViewAnimationOptionRepeat = 1 << 3, // 無限重復(fù)動(dòng)畫
UIViewAnimationOptionAutoreverse = 1 << 4, // 動(dòng)畫運(yùn)行到結(jié)束點(diǎn)后仍然以動(dòng)畫方式回到初始點(diǎn)文狱。**來回運(yùn)行動(dòng)畫,前提是設(shè)置動(dòng)畫無限重復(fù)**
UIViewAnimationOptionOverrideInheritedDuration = 1 << 5, // 忽略嵌套動(dòng)畫時(shí)間設(shè)置。**忽略外層動(dòng)畫嵌套的時(shí)間變化曲線**
UIViewAnimationOptionOverrideInheritedCurve = 1 << 6, // 忽略嵌套動(dòng)畫速度設(shè)置缘挽。**通過改變屬性和重繪實(shí)現(xiàn)動(dòng)畫效果瞄崇,如果key沒有提交動(dòng)畫將使用快照**
UIViewAnimationOptionAllowAnimatedContent = 1 << 7, // 動(dòng)畫過程中重繪視圖(注意僅僅適用于轉(zhuǎn)場動(dòng)畫)婿屹。
UIViewAnimationOptionShowHideTransitionViews = 1 << 8, // 視圖切換時(shí)直接隱藏舊視圖谤逼、顯示新視圖,而不是將舊視圖從父視圖移除(僅僅適用于轉(zhuǎn)場動(dòng)畫)**用顯隱的方式替代添加移除圖層的動(dòng)畫效果**
UIViewAnimationOptionOverrideInheritedOptions = 1 << 9, // 不繼承父動(dòng)畫設(shè)置或動(dòng)畫類型欲诺。**忽略嵌套繼承的選項(xiàng)**
// ??----------------------------------------------------------------------------
// 2.動(dòng)畫速度控制(可從其中選擇一個(gè)設(shè)置)時(shí)間函數(shù)曲線相關(guān)**時(shí)間曲線函數(shù)**
UIViewAnimationOptionCurveEaseInOut = 0 << 16, // 默認(rèn)腮郊,動(dòng)畫先緩慢楣富,然后逐漸加速。
UIViewAnimationOptionCurveEaseIn = 1 << 16, // 動(dòng)畫逐漸變慢伴榔。
UIViewAnimationOptionCurveEaseOut = 2 << 16, // 動(dòng)畫逐漸加速纹蝴。
UIViewAnimationOptionCurveLinear = 3 << 16, // 動(dòng)畫勻速執(zhí)行。
// ??-----------------------------------------------------------------------------
// 3.轉(zhuǎn)場類型(僅適用于轉(zhuǎn)場動(dòng)畫設(shè)置踪少,可以從中選擇一個(gè)進(jìn)行設(shè)置塘安,基本動(dòng)畫、關(guān)鍵幀動(dòng)畫不需要設(shè)置)**轉(zhuǎn)場動(dòng)畫相關(guān)**
UIViewAnimationOptionTransitionNone = 0 << 20, // 默認(rèn)援奢,沒有轉(zhuǎn)場動(dòng)畫效果兼犯。
UIViewAnimationOptionTransitionFlipFromLeft = 1 << 20, // 從左側(cè)翻轉(zhuǎn)效果。
UIViewAnimationOptionTransitionFlipFromRight = 2 << 20, // 從右側(cè)翻轉(zhuǎn)效果集漾。
UIViewAnimationOptionTransitionCurlUp = 3 << 20, // 向后翻頁的動(dòng)畫過渡效果切黔。
UIViewAnimationOptionTransitionCurlDown = 4 << 20, // 向前翻頁的動(dòng)畫過渡效果。
UIViewAnimationOptionTransitionCrossDissolve = 5 << 20, // 舊視圖溶解消失顯示下一個(gè)新視圖的效果具篇。
UIViewAnimationOptionTransitionFlipFromTop = 6 << 20, // 從上方翻轉(zhuǎn)效果纬霞。
UIViewAnimationOptionTransitionFlipFromBottom = 7 << 20, // 從底部翻轉(zhuǎn)效果。
// ??-----------------------------------------------------------------------------
// 4.設(shè)置幀速率
UIViewAnimationOptionPreferredFramesPerSecondDefault = 0 << 24, // 默認(rèn)的幀每秒.
UIViewAnimationOptionPreferredFramesPerSecond60 = 3 << 24, // 60幀每秒的幀速率.
UIViewAnimationOptionPreferredFramesPerSecond30 = 7 << 24, // 30幀每秒的幀速率.
/*
補(bǔ)充:關(guān)于轉(zhuǎn)場動(dòng)畫,它一般是用在這個(gè)方法中的:
[UIView transitionFromView: toView: duration: options: completion:^(****BOOL****finished) {}];
該方法效果是插入一面視圖移除一面視圖驱显,期間可以使用一些轉(zhuǎn)場動(dòng)畫效果诗芜。
*/
} NS_ENUM_AVAILABLE_IOS(4_0);
/** UIView 關(guān)鍵幀動(dòng)畫 */
typedef NS_OPTIONS(NSUInteger, UIViewKeyframeAnimationOptions) {
UIViewKeyframeAnimationOptionLayoutSubviews = UIViewAnimationOptionLayoutSubviews, //!< 動(dòng)畫過程中保證子視圖跟隨運(yùn)動(dòng).
UIViewKeyframeAnimationOptionAllowUserInteraction = UIViewAnimationOptionAllowUserInteraction, //!< 動(dòng)畫過程中允許用戶交互.
UIViewKeyframeAnimationOptionBeginFromCurrentState = UIViewAnimationOptionBeginFromCurrentState, //!< 所有視圖從當(dāng)前狀態(tài)開始運(yùn)行.
UIViewKeyframeAnimationOptionRepeat = UIViewAnimationOptionRepeat, //!< 重復(fù)運(yùn)行動(dòng)畫.
UIViewKeyframeAnimationOptionAutoreverse = UIViewAnimationOptionAutoreverse, //!< 動(dòng)畫運(yùn)行到結(jié)束點(diǎn)后仍然以動(dòng)畫方式回到初始點(diǎn).
UIViewKeyframeAnimationOptionOverrideInheritedDuration = UIViewAnimationOptionOverrideInheritedDuration, //!< 忽略嵌套動(dòng)畫時(shí)間設(shè)置.
UIViewKeyframeAnimationOptionOverrideInheritedOptions = UIViewAnimationOptionOverrideInheritedOptions, //!< 不繼承父動(dòng)畫設(shè)置或動(dòng)畫類型.
UIViewKeyframeAnimationOptionCalculationModeLinear = 0 << 10, //!< 連續(xù)運(yùn)算模式, 默認(rèn).
UIViewKeyframeAnimationOptionCalculationModeDiscrete = 1 << 10, //!< 離散運(yùn)算模式.
UIViewKeyframeAnimationOptionCalculationModePaced = 2 << 10, //!< 均勻執(zhí)行運(yùn)算模式.
UIViewKeyframeAnimationOptionCalculationModeCubic = 3 << 10, //!< 平滑運(yùn)算模式.
UIViewKeyframeAnimationOptionCalculationModeCubicPaced = 4 << 10 //!< 平滑均勻運(yùn)算模式.
} NS_ENUM_AVAILABLE_IOS(7_0);
typedef NS_ENUM(NSUInteger, UISystemAnimation) {
UISystemAnimationDelete, //!< 系統(tǒng)刪除動(dòng)畫
} NS_ENUM_AVAILABLE_IOS(7_0);
typedef NS_ENUM(NSInteger, UIViewTintAdjustmentMode) {
UIViewTintAdjustmentModeAutomatic, //!< 自動(dòng)的瞳抓,與父視圖相同.
UIViewTintAdjustmentModeNormal, //!< 未經(jīng)修改的.
UIViewTintAdjustmentModeDimmed, //!< 飽和、暗淡的原始色.
} NS_ENUM_AVAILABLE_IOS(7_0);
typedef NS_ENUM(NSInteger, UISemanticContentAttribute) {
UISemanticContentAttributeUnspecified = 0, //!< 未指定伏恐,默認(rèn)值
UISemanticContentAttributePlayback, //!< 打開/ RW / FF等播放控制按鈕
UISemanticContentAttributeSpatial, //!< 控制導(dǎo)致某種形式的定向改變UI中,如分段控制文本對齊方式或在游戲中方向鍵
UISemanticContentAttributeForceLeftToRight, //!< 視圖總是從左向右布局.
UISemanticContentAttributeForceRightToLeft //!< 視圖總是從右向左布局.
} NS_ENUM_AVAILABLE_IOS(9_0);
@protocol UICoordinateSpace <NSObject>
/** 將像素point由point所在視圖轉(zhuǎn)換到目標(biāo)視圖view中孩哑,返回在目標(biāo)視圖view中的像素值 */
- (CGPoint)convertPoint:(CGPoint)point toCoordinateSpace:(id <UICoordinateSpace>)coordinateSpace NS_AVAILABLE_IOS(8_0);
/** 將像素point由point所在視圖轉(zhuǎn)換到目標(biāo)視圖view中,返回在目標(biāo)視圖view中的像素值 */
- (CGPoint)convertPoint:(CGPoint)point fromCoordinateSpace:(id <UICoordinateSpace>)coordinateSpace NS_AVAILABLE_IOS(8_0);
/** 將rect由rect所在視圖轉(zhuǎn)換到目標(biāo)視圖view中翠桦,返回在目標(biāo)視圖view中的rect */
- (CGRect)convertRect:(CGRect)rect toCoordinateSpace:(id <UICoordinateSpace>)coordinateSpace NS_AVAILABLE_IOS(8_0);
/** 將rect從view中轉(zhuǎn)換到當(dāng)前視圖中横蜒,返回在當(dāng)前視圖中的rect */
- (CGRect)convertRect:(CGRect)rect fromCoordinateSpace:(id <UICoordinateSpace>)coordinateSpace NS_AVAILABLE_IOS(8_0);
/** 獲取bounds */
@property (readonly, nonatomic) CGRect bounds NS_AVAILABLE_IOS(8_0);
@end
@class UIBezierPath, UIEvent, UIWindow, UIViewController, UIColor, UIGestureRecognizer, UIMotionEffect, CALayer, UILayoutGuide;
// ??----------------------------------------------------------------------------
// UIView
NS_CLASS_AVAILABLE_IOS(2_0) @interface UIView : UIResponder <NSCoding, UIAppearance, UIAppearanceContainer, UIDynamicItem, UITraitEnvironment, UICoordinateSpace, UIFocusItem, CALayerDelegate>
/** 返回主 layer 所使用的類 */
#if UIKIT_DEFINE_AS_PROPERTIES
@property(class, nonatomic, readonly) Class layerClass;
#else
+ (Class)layerClass;
#endif
/** 通過設(shè)置 Frame 初始化 UIView 對象 */
- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
/** 用于xib初始化 */
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder NS_DESIGNATED_INITIALIZER;
/** 設(shè)置用戶交互,默認(rèn)YES允許用戶交互 */
@property(nonatomic,getter=isUserInteractionEnabled) BOOL userInteractionEnabled;
/** 控件標(biāo)記(父控件可以通過tag找到對應(yīng)的子控件)销凑,默認(rèn)為0 */
@property(nonatomic) NSInteger tag;
/** 視圖圖層(可以用來設(shè)置圓角效果/陰影效果) */
@property(nonatomic,readonly,strong) CALayer *layer;
/** 返回是否可以成為焦點(diǎn), 默認(rèn)NO */
#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic,readonly) BOOL canBecomeFocused NS_AVAILABLE_IOS(9_0);
#else
- (BOOL)canBecomeFocused NS_AVAILABLE_IOS(9_0);
#endif
/** 是否可以被聚焦 */
@property (readonly, nonatomic, getter=isFocused) BOOL focused NS_AVAILABLE_IOS(9_0);
/** 左右滑動(dòng)翻轉(zhuǎn)效果 */
@property (nonatomic) UISemanticContentAttribute semanticContentAttribute NS_AVAILABLE_IOS(9_0);
/** 獲取視圖的方向 */
+ (UIUserInterfaceLayoutDirection)userInterfaceLayoutDirectionForSemanticContentAttribute:(UISemanticContentAttribute)attribute NS_AVAILABLE_IOS(9_0);
/** 獲取相對于指定視圖的界面方向 */
+ (UIUserInterfaceLayoutDirection)userInterfaceLayoutDirectionForSemanticContentAttribute:(UISemanticContentAttribute)semanticContentAttribute relativeToLayoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection NS_AVAILABLE_IOS(10_0);
/** 返回即時(shí)內(nèi)容的布局的方向 */
@property (readonly, nonatomic) UIUserInterfaceLayoutDirection effectiveUserInterfaceLayoutDirection NS_AVAILABLE_IOS(10_0);
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類丛晌,幾何
@interface UIView(UIViewGeometry)
/** 位置和尺寸(以父控件的左上角為坐標(biāo)原點(diǎn)(0, 0)) */
@property(nonatomic) CGRect frame;
/** 位置和尺寸(以自己的左上角為坐標(biāo)原點(diǎn)(0, 0)) */
@property(nonatomic) CGRect bounds;
/** 中心點(diǎn)(以父控件的左上角為坐標(biāo)原點(diǎn)(0, 0)) */
@property(nonatomic) CGPoint center;
/** 變形屬性(平移\縮放\旋轉(zhuǎn)) */
@property(nonatomic) CGAffineTransform transform;
/** 視圖內(nèi)容的縮放比例 */
@property(nonatomic) CGFloat contentScaleFactor NS_AVAILABLE_IOS(4_0);
/** 是否支持多點(diǎn)觸摸,默認(rèn)NO */
@property(nonatomic,getter=isMultipleTouchEnabled) BOOL multipleTouchEnabled __TVOS_PROHIBITED;
/** 是否獨(dú)占整個(gè)Touch事件闻鉴,默認(rèn)NO */
@property(nonatomic,getter=isExclusiveTouch) BOOL exclusiveTouch __TVOS_PROHIBITED;
/** 在指定點(diǎn)上點(diǎn)擊測試指定事件 */
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;
/** 判斷當(dāng)前的點(diǎn)擊或者觸摸事件的點(diǎn)是否在當(dāng)前的view中,默認(rèn)返回YES */
- (BOOL)pointInside:(CGPoint)point withEvent:(nullable UIEvent *)event;
/** 將像素point由point所在視圖轉(zhuǎn)換到目標(biāo)視圖view中茂洒,返回在目標(biāo)視圖view中的像素值 */
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;
/** 將像素point由point所在視圖轉(zhuǎn)換到目標(biāo)視圖view中孟岛,返回在目標(biāo)視圖view中的像素值 */
- (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;
/** 將rect由rect所在視圖轉(zhuǎn)換到目標(biāo)視圖view中,返回在目標(biāo)視圖view中的rect */
- (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
/** 將rect從view中轉(zhuǎn)換到當(dāng)前視圖中督勺,返回在當(dāng)前視圖中的rect */
- (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
/** 自動(dòng)調(diào)整子視圖尺寸渠羞,默認(rèn)YES,如果 self.bounds 改變了智哀,則會(huì)根據(jù) autoresizingMask 屬性自動(dòng)調(diào)整子視圖尺寸 */
@property(nonatomic) BOOL autoresizesSubviews;
/** 自動(dòng)調(diào)整子視圖與父視圖的位置次询,默認(rèn) UIViewAutoresizingNone */
@property(nonatomic) UIViewAutoresizing autoresizingMask;
/** 返回“最佳”尺寸以適應(yīng)給定尺寸。不實(shí)際調(diào)整視圖大小瓷叫。默認(rèn)為返回現(xiàn)有視圖大小屯吊。*/
- (CGSize)sizeThatFits:(CGSize)size;
/** 調(diào)整為剛好合適子視圖大小 */
- (void)sizeToFit;
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類,視圖層次結(jié)構(gòu)
@interface UIView(UIViewHierarchy)
/** 獲取父視圖 */
@property(nullable, nonatomic,readonly) UIView *superview;
/** 獲取所有子視圖 */
@property(nonatomic,readonly,copy) NSArray<__kindof UIView *> *subviews;
/** 獲取視圖所在的Window */
@property(nullable, nonatomic,readonly) UIWindow *window;
/** 從父視圖中移除控件 */
- (void)removeFromSuperview;
/** 插入子視圖(將子視圖插入到subviews數(shù)組中index這個(gè)位置) */
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
/** 交換subviews數(shù)組中所存放子視圖的位置 */
- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;
/** 添加子視圖(新添加的視圖在subviews數(shù)組的后面, 顯示在最上面) */
- (void)addSubview:(UIView *)view;
/** 插入子視圖(將子視圖插到siblingSubview之下) */
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
/** 插入子視圖(將子視圖插到siblingSubview之上) */
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;
/** 將子視圖拉到最上面來顯示 */
- (void)bringSubviewToFront:(UIView *)view;
/** 將子視圖拉到最下面來顯示 */
- (void)sendSubviewToBack:(UIView *)view;
#pragma mark - 系統(tǒng)自動(dòng)調(diào)用(留給子類去實(shí)現(xiàn))
/** 添加子視圖完成后調(diào)用 */
- (void)didAddSubview:(UIView *)subview;
/** 將要移除子視圖時(shí)調(diào)用 */
- (void)willRemoveSubview:(UIView *)subview;
/** 將要移動(dòng)到新父視圖時(shí)調(diào)用 */
- (void)willMoveToSuperview:(nullable UIView *)newSuperview;
/** 移動(dòng)到新父視圖完成后調(diào)用 */
- (void)didMoveToSuperview;
/** 將要移動(dòng)到新 Window 時(shí)調(diào)用 */
- (void)willMoveToWindow:(nullable UIWindow *)newWindow;
/** 移動(dòng)到新 Window 完成后調(diào)用 */
- (void)didMoveToWindow;
/** 判斷view是否為子類 */
- (BOOL)isDescendantOfView:(UIView *)view;
/** 通過tag獲得對應(yīng)的子視圖 */
- (nullable __kindof UIView *)viewWithTag:(NSInteger)tag;
/** 對現(xiàn)在有布局有調(diào)整更改后摹菠,使用這個(gè)方法進(jìn)行更新 */
- (void)setNeedsLayout;
/** 強(qiáng)制進(jìn)行更新layout */
- (void)layoutIfNeeded;
/** 控件的frame發(fā)生改變的時(shí)候就會(huì)調(diào)用,一般在這里重寫布局子控件的位置和尺寸 */
- (void)layoutSubviews;
/** 設(shè)置view之間的間距盒卸,該屬性只對autolayout布局有效 */
@property (nonatomic) UIEdgeInsets layoutMargins NS_AVAILABLE_IOS(8_0);
/** 是否將當(dāng)前視圖的間距和父視圖相同,默認(rèn)是NO */
@property (nonatomic) BOOL preservesSuperviewLayoutMargins NS_AVAILABLE_IOS(8_0);
/** 改變view的layoutMargins這個(gè)屬性時(shí)次氨,會(huì)觸發(fā)這個(gè)方法 */
- (void)layoutMarginsDidChange NS_AVAILABLE_IOS(8_0);
/** 視圖間距引導(dǎo) */
@property(readonly,strong) UILayoutGuide *layoutMarginsGuide NS_AVAILABLE_IOS(9_0);
/** 獲取此區(qū)域的內(nèi)的布局引導(dǎo) */
@property (nonatomic, readonly, strong) UILayoutGuide *readableContentGuide NS_AVAILABLE_IOS(9_0);
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類蔽介,視圖渲染
@interface UIView(UIViewRendering)
/** 重寫drawRect方法,在可以這里進(jìn)行繪圖操作煮寡。*/
- (void)drawRect:(CGRect)rect;
/** 標(biāo)記整個(gè)視圖的邊界矩形需要重繪, 調(diào)用這個(gè)方法會(huì)自動(dòng)調(diào)用drawRect方法 */
- (void)setNeedsDisplay;
/** 標(biāo)記在指定區(qū)域內(nèi)的視圖的邊界需要重繪, 調(diào)用這個(gè)方法會(huì)自動(dòng)調(diào)用drawRect方法 */
- (void)setNeedsDisplayInRect:(CGRect)rect;
/** 是否裁剪超出Bounds范圍的子控件虹蓄,默認(rèn)NO */
@property(nonatomic) BOOL clipsToBounds;
/** 設(shè)置背景顏色,默認(rèn)nil */
@property(nullable, nonatomic,copy) UIColor *backgroundColor UI_APPEARANCE_SELECTOR;
/** 設(shè)置透明度(范圍0.0~1.0)幸撕,默認(rèn)1.0 */
@property(nonatomic) CGFloat alpha;
/** 設(shè)置是否不透明薇组,默認(rèn)YES不透明 */
@property(nonatomic,getter=isOpaque) BOOL opaque;
/** 視圖重繪前是否先清理以前的內(nèi)容,默認(rèn)YES */
@property(nonatomic) BOOL clearsContextBeforeDrawing;
/** 設(shè)置是否隱藏坐儿,默認(rèn)NO不隱藏 */
@property(nonatomic,getter=isHidden) BOOL hidden;
/** 內(nèi)容顯示的模式体箕,默認(rèn)UIViewContentModeScaleToFill */
@property(nonatomic) UIViewContentMode contentMode;
/** 拉伸屬性专钉,如圖片拉伸 */
@property(nonatomic) CGRect contentStretch NS_DEPRECATED_IOS(3_0,6_0) __TVOS_PROHIBITED;
/** 蒙板view */
@property(nullable, nonatomic,strong) UIView *maskView NS_AVAILABLE_IOS(8_0);
/** 改變應(yīng)用程序的外觀的顏色。默認(rèn)為nil */
@property(null_resettable, nonatomic, strong) UIColor *tintColor NS_AVAILABLE_IOS(7_0);
/** 可以使tintColor變暗累铅,因此整個(gè)視圖層次變暗 */
@property(nonatomic) UIViewTintAdjustmentMode tintAdjustmentMode NS_AVAILABLE_IOS(7_0);
/** 覆蓋這個(gè)方法的目的是為了當(dāng)tintColor改變的時(shí)候自定義一些行為 */
- (void)tintColorDidChange NS_AVAILABLE_IOS(7_0);
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類跃须,視圖動(dòng)畫
@interface UIView(UIViewAnimation)
/** 開始動(dòng)畫 */
+ (void)beginAnimations:(nullable NSString *)animationID context:(nullable voidvoid *)context;
/** 提交動(dòng)畫 */
+ (void)commitAnimations;
/** 設(shè)置動(dòng)畫代理, 默認(rèn)nil */
+ (void)setAnimationDelegate:(nullable id)delegate;
/** 動(dòng)畫將要開始時(shí)執(zhí)行方法(必須要先設(shè)置動(dòng)畫代理), 默認(rèn)NULL */
+ (void)setAnimationWillStartSelector:(nullable SEL)selector;
/** 動(dòng)畫已結(jié)束時(shí)執(zhí)行方法(必須要先設(shè)置動(dòng)畫代理), 默認(rèn)NULL */
+ (void)setAnimationDidStopSelector:(nullable SEL)selector;
/** 設(shè)置動(dòng)畫時(shí)長, 默認(rèn)0.2秒 */
+ (void)setAnimationDuration:(NSTimeInterval)duration;
/** 動(dòng)畫延遲執(zhí)行時(shí)間, 默認(rèn)0.0秒 */
+ (void)setAnimationDelay:(NSTimeInterval)delay;
/** 設(shè)置在動(dòng)畫塊內(nèi)部動(dòng)畫屬性改變的開始時(shí)間, 默認(rèn)now ([NSDate date]) */
+ (void)setAnimationStartDate:(NSDate *)startDate;
/** 設(shè)置動(dòng)畫曲線, 默認(rèn)UIViewAnimationCurveEaseInOut */
+ (void)setAnimationCurve:(UIViewAnimationCurve)curve;
/** 動(dòng)畫的重復(fù)播放次數(shù), 默認(rèn)0 */
+ (void)setAnimationRepeatCount:(float)repeatCount;
/** 設(shè)置是否自定翻轉(zhuǎn)當(dāng)前的動(dòng)畫效果, 默認(rèn)NO */
+ (void)setAnimationRepeatAutoreverses:(BOOL)repeatAutoreverses;
/** 設(shè)置動(dòng)畫從當(dāng)前狀態(tài)開始播放, 默認(rèn)NO */
+ (void)setAnimationBeginsFromCurrentState:(BOOL)fromCurrentState;
/** 在動(dòng)畫塊中為視圖設(shè)置過渡動(dòng)畫 */
+ (void)setAnimationTransition:(UIViewAnimationTransition)transition forView:(UIView *)view cache:(BOOL)cache;
/** 設(shè)置是否激活動(dòng)畫 */
+ (void)setAnimationsEnabled:(BOOL)enabled;
/** 返回一個(gè)布爾值表示動(dòng)畫是否結(jié)束 */
#if UIKIT_DEFINE_AS_PROPERTIES
@property(class, nonatomic, readonly) BOOL areAnimationsEnabled;
#else
+ (BOOL)areAnimationsEnabled;
#endif
/** 先檢查動(dòng)畫當(dāng)前是否啟用娃兽,然后禁止動(dòng)畫菇民,執(zhí)行block內(nèi)的方法,最后重新啟用動(dòng)畫投储,而且這個(gè)方法不會(huì)阻塞基于CoreAnimation的動(dòng)畫 */
+ (void)performWithoutAnimation:(void (NS_NOESCAPE ^)(void))actionsWithoutAnimation NS_AVAILABLE_IOS(7_0);
/** 當(dāng)前動(dòng)畫的持續(xù)時(shí)間 */
#if UIKIT_DEFINE_AS_PROPERTIES
@property(class, nonatomic, readonly) NSTimeInterval inheritedAnimationDuration NS_AVAILABLE_IOS(9_0);
#else
+ (NSTimeInterval)inheritedAnimationDuration NS_AVAILABLE_IOS(9_0);
#endif
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類第练,用 Blocks 方式實(shí)現(xiàn)視圖動(dòng)畫
@interface UIView(UIViewAnimationWithBlocks)
/**
通過指定動(dòng)畫持續(xù)時(shí)間、動(dòng)畫延遲玛荞、執(zhí)行動(dòng)畫選項(xiàng)和動(dòng)畫完成后回調(diào)的 Block 對象,更改一個(gè)或多個(gè)視圖的動(dòng)畫娇掏。
*/
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);
/**
通過指定動(dòng)畫持續(xù)時(shí)間、動(dòng)畫完成后回調(diào)的 Block 對象,更改一個(gè)或多個(gè)視圖的動(dòng)畫勋眯。
默認(rèn):delay = 0.0, options = 0
*/
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(4_0);
/**
通過指定動(dòng)畫持續(xù)時(shí)間更改一個(gè)或多個(gè)視圖的動(dòng)畫婴梧。
默認(rèn):delay = 0.0, options = 0, completion = NULL
*/
+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations NS_AVAILABLE_IOS(4_0);
/** 使用與物理彈簧運(yùn)動(dòng)相對應(yīng)的定時(shí)曲線執(zhí)行視圖動(dòng)畫 */
+ (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);
/** 為指定的容器視圖創(chuàng)建轉(zhuǎn)換動(dòng)畫 */
+ (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);
/** 使用給定的參數(shù)在指定視圖之間創(chuàng)建轉(zhuǎn)換動(dòng)畫 */
+ (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
/** 在一個(gè)或多個(gè)視圖上執(zhí)行指定的系統(tǒng)提供的動(dòng)畫,以及定義的可選并行動(dòng)畫 */
+ (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);
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類客蹋,UIView 的關(guān)鍵幀動(dòng)畫
@interface UIView (UIViewKeyframeAnimations)
/** 創(chuàng)建一個(gè)動(dòng)畫塊對象塞蹭,可用于為當(dāng)前視圖設(shè)置基于關(guān)鍵幀的動(dòng)畫 */
+ (void)animateKeyframesWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewKeyframeAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);
/** 添加指定開始時(shí)間、持續(xù)時(shí)間的關(guān)鍵幀動(dòng)畫(起始和持續(xù)時(shí)間是0.0和1.0之間的值) */
+ (void)addKeyframeWithRelativeStartTime:(double)frameStartTime relativeDuration:(double)frameDuration animations:(void (^)(void))animations NS_AVAILABLE_IOS(7_0);
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類讶坯,手勢識(shí)別
@interface UIView (UIViewGestureRecognizers)
/** 當(dāng)前視圖所附加的所有手勢識(shí)別器 */
@property(nullable, nonatomic,copy) NSArray<__kindof UIGestureRecognizer *> *gestureRecognizers NS_AVAILABLE_IOS(3_2);
/** 添加一個(gè)手勢識(shí)別器 */
- (void)addGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer NS_AVAILABLE_IOS(3_2);
/** 移除一個(gè)手勢識(shí)別器 */
- (void)removeGestureRecognizer:(UIGestureRecognizer*)gestureRecognizer NS_AVAILABLE_IOS(3_2);
/** 是否開始一個(gè)手勢識(shí)別器 */
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer NS_AVAILABLE_IOS(6_0);
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類番电,UIView 運(yùn)動(dòng)效果
@interface UIView (UIViewMotionEffects)
/** 添加運(yùn)動(dòng)效果,當(dāng)傾斜設(shè)備時(shí)視圖稍微改變其位置 */
- (void)addMotionEffect:(UIMotionEffect *)effect NS_AVAILABLE_IOS(7_0);
/** 移除運(yùn)動(dòng)效果 */
- (void)removeMotionEffect:(UIMotionEffect *)effect NS_AVAILABLE_IOS(7_0);
/** 所有添加的運(yùn)動(dòng)效果 */
@property (copy, nonatomic) NSArray<__kindof UIMotionEffect *> *motionEffects NS_AVAILABLE_IOS(7_0);
@end
typedef NS_ENUM(NSInteger, UILayoutConstraintAxis) {
UILayoutConstraintAxisHorizontal = 0, //!< 水平約束.
UILayoutConstraintAxisVertical = 1 //!< 豎直約束.
};
// ??----------------------------------------------------------------------------
// UIView 范疇類辆琅,UIView 布局約束設(shè)置
@interface UIView (UIConstraintBasedLayoutInstallingConstraints)
/** 獲取所有約束 */
@property(nonatomic,readonly) NSArray<__kindof NSLayoutConstraint *> *constraints NS_AVAILABLE_IOS(6_0);
/** 添加一個(gè)約束 */
- (void)addConstraint:(NSLayoutConstraint *)constraint NS_AVAILABLE_IOS(6_0);
/** 添加多個(gè)約束 */
- (void)addConstraints:(NSArray<__kindof NSLayoutConstraint *> *)constraints NS_AVAILABLE_IOS(6_0);
/** 移除一個(gè)約束 */
- (void)removeConstraint:(NSLayoutConstraint *)constraint NS_AVAILABLE_IOS(6_0);
/** 移除多個(gè)約束 */
- (void)removeConstraints:(NSArray<__kindof NSLayoutConstraint *> *)constraints NS_AVAILABLE_IOS(6_0);
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類漱办,UIView 基于約束的布局核心方法
@interface UIView (UIConstraintBasedLayoutCoreMethods)
/** 更新視圖和其子視圖的約束 */
- (void)updateConstraintsIfNeeded NS_AVAILABLE_IOS(6_0);
/** 為視圖更新約束,可以重寫這個(gè)方法來設(shè)置當(dāng)前view局部的布局約束 */
- (void)updateConstraints NS_AVAILABLE_IOS(6_0) NS_REQUIRES_SUPER;
/** 視圖的約束是否需要更新 */
- (BOOL)needsUpdateConstraints NS_AVAILABLE_IOS(6_0);
/** 設(shè)置視圖的約束需要更新婉烟,調(diào)用這個(gè)方法洼冻,系統(tǒng)會(huì)調(diào)用updateConstraints去更新布局 */
- (void)setNeedsUpdateConstraints NS_AVAILABLE_IOS(6_0);
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類,UIView 約束兼容性設(shè)置
@interface UIView (UIConstraintBasedCompatibility)
/** 是否啟用自動(dòng)布局約束隅很,默認(rèn)YES. IB默認(rèn)是NO */
@property(nonatomic) BOOL translatesAutoresizingMaskIntoConstraints NS_AVAILABLE_IOS(6_0);
/** 是否使用約束布局 */
#if UIKIT_DEFINE_AS_PROPERTIES
@property(class, nonatomic, readonly) BOOL requiresConstraintBasedLayout NS_AVAILABLE_IOS(6_0);
#else
+ (BOOL)requiresConstraintBasedLayout NS_AVAILABLE_IOS(6_0);
#endif
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類撞牢,UIView 布局圖層約束
@interface UIView (UIConstraintBasedLayoutLayering)
/** 返回給定框架的視圖的對齊矩陣 */
- (CGRect)alignmentRectForFrame:(CGRect)frame NS_AVAILABLE_IOS(6_0);
/** 返回給定對齊矩形的視圖的frame */
- (CGRect)frameForAlignmentRect:(CGRect)alignmentRect NS_AVAILABLE_IOS(6_0);
/** 返回從視圖的frame上定義的對齊矩陣的邊框 */
#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic, readonly) UIEdgeInsets alignmentRectInsets NS_AVAILABLE_IOS(6_0);
#else
- (UIEdgeInsets)alignmentRectInsets NS_AVAILABLE_IOS(6_0);
#endif
/** 返回滿足基線約束條件的視圖 */
- (UIView *)viewForBaselineLayout NS_DEPRECATED_IOS(6_0, 9_0, "Override -viewForFirstBaselineLayout or -viewForLastBaselineLayout as appropriate, instead") __TVOS_PROHIBITED;
/** 返回用于滿足第一基線約束的視圖 */
@property(readonly,strong) UIView *viewForFirstBaselineLayout NS_AVAILABLE_IOS(9_0);
/** 返回用于滿足上次基線約束的視圖 */
@property(readonly,strong) UIView *viewForLastBaselineLayout NS_AVAILABLE_IOS(9_0);
UIKIT_EXTERN const CGFloat UIViewNoIntrinsicMetric NS_AVAILABLE_IOS(6_0); // -1
/** 返回接收對象的原本大小 */
#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic, readonly) CGSize intrinsicContentSize NS_AVAILABLE_IOS(6_0);
#else
- (CGSize)intrinsicContentSize NS_AVAILABLE_IOS(6_0);
#endif
/** 廢除視圖原本內(nèi)容的size */
- (void)invalidateIntrinsicContentSize NS_AVAILABLE_IOS(6_0);
/** 設(shè)置當(dāng)視圖要變大時(shí),視圖的壓縮改變方式叔营,返回一個(gè)優(yōu)先權(quán)(確定view有多大的優(yōu)先級阻止自己變大) */
- (UILayoutPriority)contentHuggingPriorityForAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
/** 設(shè)置放先權(quán) */
- (void)setContentHuggingPriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
/** 設(shè)置當(dāng)視圖要變小時(shí)屋彪,視圖的壓縮改變方式,是水平縮小還是垂直縮小绒尊,并返回一個(gè)優(yōu)先權(quán)(確定有多大的優(yōu)先級阻止自己變行蠡印) */
- (UILayoutPriority)contentCompressionResistancePriorityForAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
/** 設(shè)置優(yōu)先權(quán) */
- (void)setContentCompressionResistancePriority:(UILayoutPriority)priority forAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
@end
// Size To Fit
UIKIT_EXTERN const CGSize UILayoutFittingCompressedSize NS_AVAILABLE_IOS(6_0);
UIKIT_EXTERN const CGSize UILayoutFittingExpandedSize NS_AVAILABLE_IOS(6_0);
// ??----------------------------------------------------------------------------
// UIView 范疇類,UIView 布局?jǐn)M合尺寸
@interface UIView (UIConstraintBasedLayoutFittingSize)
/** 返回滿足持有約束的視圖的size */
- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize NS_AVAILABLE_IOS(6_0);
/** 返回滿足它所包含的約束的視圖的大小 */
- (CGSize)systemLayoutSizeFittingSize:(CGSize)targetSize withHorizontalFittingPriority:(UILayoutPriority)horizontalFittingPriority verticalFittingPriority:(UILayoutPriority)verticalFittingPriority NS_AVAILABLE_IOS(8_0);
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類婴谱,UIView 布局指南支持
@interface UIView (UILayoutGuideSupport)
/** 此視圖擁有布局向?qū)ο蟮臄?shù)組 */
@property(nonatomic,readonly,copy) NSArray<__kindof UILayoutGuide *> *layoutGuides NS_AVAILABLE_IOS(9_0);
/** 向視圖中添加布局向?qū)?*/
- (void)addLayoutGuide:(UILayoutGuide *)layoutGuide NS_AVAILABLE_IOS(9_0);
/** 向視圖中添加布局向?qū)?*/
- (void)removeLayoutGuide:(UILayoutGuide *)layoutGuide NS_AVAILABLE_IOS(9_0);
@end
@class NSLayoutXAxisAnchor,NSLayoutYAxisAnchor,NSLayoutDimension;
@interface UIView (UIViewLayoutConstraintCreation)
/** 布局視圖的前緣框的布局錨點(diǎn) */
@property(readonly, strong) NSLayoutXAxisAnchor *leadingAnchor NS_AVAILABLE_IOS(9_0);
/** 布局視圖的后緣邊框的布局錨點(diǎn) */
@property(readonly, strong) NSLayoutXAxisAnchor *trailingAnchor NS_AVAILABLE_IOS(9_0);
/** 布局視圖的左邊框的布局錨點(diǎn) */
@property(readonly, strong) NSLayoutXAxisAnchor *leftAnchor NS_AVAILABLE_IOS(9_0);
/** 布局視圖的右邊框的布局錨點(diǎn) */
@property(readonly, strong) NSLayoutXAxisAnchor *rightAnchor NS_AVAILABLE_IOS(9_0);
/** 布局視圖的頂邊框的布局錨點(diǎn) */
@property(readonly, strong) NSLayoutYAxisAnchor *topAnchor NS_AVAILABLE_IOS(9_0);
/** 布局視圖的底邊框的布局錨點(diǎn) */
@property(readonly, strong) NSLayoutYAxisAnchor *bottomAnchor NS_AVAILABLE_IOS(9_0);
/** 布局視圖的寬度 */
@property(readonly, strong) NSLayoutDimension *widthAnchor NS_AVAILABLE_IOS(9_0);
/** 布局視圖的高度 */
@property(readonly, strong) NSLayoutDimension *heightAnchor NS_AVAILABLE_IOS(9_0);
/** 布局視圖的水平中心軸 */
@property(readonly, strong) NSLayoutXAxisAnchor *centerXAnchor NS_AVAILABLE_IOS(9_0);
/** 布局視圖的垂直中心軸 */
@property(readonly, strong) NSLayoutYAxisAnchor *centerYAnchor NS_AVAILABLE_IOS(9_0);
/** 一個(gè)代表對視圖中的文本的最高線基線布置錨 */
@property(readonly, strong) NSLayoutYAxisAnchor *firstBaselineAnchor NS_AVAILABLE_IOS(9_0);
/** 一個(gè)代表對視圖中的文本的最低線基線布置錨 */
@property(readonly, strong) NSLayoutYAxisAnchor *lastBaselineAnchor NS_AVAILABLE_IOS(9_0);
@end
// ??----------------------------------------------------------------------------
// UIView 范疇類蟹但,UIView 布局調(diào)試
@interface UIView (UIConstraintBasedLayoutDebugging)
/** 獲得實(shí)體在不同方向上所有的布局約束 */
- (NSArray<__kindof NSLayoutConstraint *> *)constraintsAffectingLayoutForAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(6_0);
/** 可以知道當(dāng)前視圖的布局是否會(huì)有歧義 */
#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic, readonly) BOOL hasAmbiguousLayout NS_AVAILABLE_IOS(6_0);
#else
- (BOOL)hasAmbiguousLayout NS_AVAILABLE_IOS(6_0);
#endif
/** 這個(gè)方法會(huì)隨機(jī)改變視圖的layout到另外一個(gè)有效的layout躯泰。這樣我們就可以很清楚的看到哪一個(gè)layout導(dǎo)致了整體的布局約束出現(xiàn)了錯(cuò)誤,或者我們應(yīng)該增加更多的布局約束 */
- (void)exerciseAmbiguityInLayout NS_AVAILABLE_IOS(6_0);
@end
// ??----------------------------------------------------------------------------
/** 約束調(diào)試华糖,只在DEBUG環(huán)境下被調(diào)用 */
@interface UILayoutGuide (UIConstraintBasedLayoutDebugging)
/** 獲得實(shí)體在不同方向上所有的布局約束 */
- (NSArray<__kindof NSLayoutConstraint *> *)constraintsAffectingLayoutForAxis:(UILayoutConstraintAxis)axis NS_AVAILABLE_IOS(10_0);
/** 可以知道當(dāng)前視圖的布局是否會(huì)有歧義 */
#if UIKIT_DEFINE_AS_PROPERTIES
@property(nonatomic, readonly) BOOL hasAmbiguousLayout NS_AVAILABLE_IOS(10_0);
#else
- (BOOL)hasAmbiguousLayout NS_AVAILABLE_IOS(10_0);
#endif
@end
// ??----------------------------------------------------------------------------
#pragma mark - View狀態(tài)保存恢復(fù)
@interface UIView (UIStateRestoration)
/** 標(biāo)示是否支持保存,恢復(fù)視圖狀態(tài)信息 */
@property (nullable, nonatomic, copy) NSString *restorationIdentifier NS_AVAILABLE_IOS(6_0);
/** 保存視圖狀態(tài)相關(guān)的信息 */
- (void) encodeRestorableStateWithCoder:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
/** 恢復(fù)和保持視圖狀態(tài)相關(guān)信息 */
- (void) decodeRestorableStateWithCoder:(NSCoder *)coder NS_AVAILABLE_IOS(6_0);
@end
// ??----------------------------------------------------------------------------
#pragma mark - View快照
@interface UIView (UISnapshotting)
/** 將當(dāng)前顯示的view截取成一個(gè)新的view */
- (nullable UIView *)snapshotViewAfterScreenUpdates:(BOOL)afterUpdates NS_AVAILABLE_IOS(7_0);
/** 縮放一個(gè)view默認(rèn)是從中心點(diǎn)進(jìn)行縮放的 */
- (nullable UIView *)resizableSnapshotViewFromRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates withCapInsets:(UIEdgeInsets)capInsets NS_AVAILABLE_IOS(7_0);
/** 屏幕快照 */
- (BOOL)drawViewHierarchyInRect:(CGRect)rect afterScreenUpdates:(BOOL)afterUpdates NS_AVAILABLE_IOS(7_0);
@end
NS_ASSUME_NONNULL_END