OC--UIView基础

作者: 啊哈呵 | 来源:发表于2017-03-14 08:51 被阅读34次

    基本属性方法

    @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];
                                  }];
    }
    

    相关文章

      网友评论

        本文标题:OC--UIView基础

        本文链接:https://www.haomeiwen.com/subject/qviqnttx.html