JHChainableAnimations 源码阅读

本文详细解析了JHChainableAnimations库的链式编程实现方式,包括链式调用的具体方法如makeFrame、makeBounds等,并介绍了如何通过链式调用实现UIView的动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JHChainableAnimations 源码阅读(2)

JHChainableAnimations 支持链式编程。链式编程 在OC中的实现就是,函数返回一个Block,并且在外面调用这个block,传入block计算所需要的参数。并且block返回对象本身,这样子就可以继续调用了

链式编程特点:方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)

Masonry 自动布局的框架也是链式编程有空继续分析

UIView (UIView_JHChainableAnimations)定义了一些UIView的常用操作

改变大小OR位移

- (JHChainableRect) makeFrame;
- (JHChainableRect) makeBounds;
- (JHChainableSize) makeSize;
- (JHChainablePoint) makeOrigin;
- (JHChainablePoint) makeCenter;
- (JHChainableFloat) makeX;
- (JHChainableFloat) makeY;
- (JHChainableFloat) makeWidth;
- (JHChainableFloat) makeHeight;
- (JHChainableFloat) makeOpacity;
- (JHChainableColor) makeBackground;
- (JHChainableColor) makeBorderColor;
- (JHChainableFloat) makeBorderWidth;
- (JHChainableFloat) makeCornerRadius;
- (JHChainableFloat) makeScale;
- (JHChainableFloat) makeScaleX;
- (JHChainableFloat) makeScaleY;
- (JHChainablePoint) makeAnchor;

……

接下来分析一个具体的实现看看比如

makeFrame

-(JHChainableRect)makeFrame {
JHChainableRect chainable = JHChainableRect(rect){
    return self.makeOrigin(rect.origin.x, rect.origin.y).makeBounds(rect);
    };
    return chainable;
}

>
JHChainableRect block 传入参数 CGRectrect 然后调用 self.makeOrigin 修改Origin 再调用makeBounds 修改大小

-(JHChainablePoint)makeOrigin {
    JHChainablePoint chainable = JHChainablePoint(x, y) {
        //修改position
        [self addAnimationCalculationAction:^(UIView *weakSelf) {
            JHKeyframeAnimation *positionAnimation = [weakSelf basicAnimationForKeyPath:@"position"];
            CGPoint newPosition = [weakSelf newPositionFromNewOrigin:CGPointMake(x, y)];
            positionAnimation.fromValue = [NSValue valueWithCGPoint:weakSelf.layer.position];
            positionAnimation.toValue = [NSValue valueWithCGPoint:newPosition];
            [weakSelf addAnimationFromCalculationBlock:positionAnimation];
        }];
        //动画结束结束之后,修改最终的结果
        [self addAnimationCompletionAction:^(UIView *weakSelf) {
            CGPoint newPosition = [weakSelf newPositionFromNewOrigin:CGPointMake(x, y)];
            weakSelf.layer.position = newPosition;
        }];

        return self;
    };
    return chainable;}

    -(JHChainableRect)makeBounds {
    JHChainableRect chainable = JHChainableRect(rect) {
        //修改大小
        return self.makeSize(rect.size.width, rect.size.height);
    };
    return chainable;
}

- (JHChainableSize) makeSize {
    JHChainableSize chainable = JHChainableSize(width, height){

        [self addAnimationCalculationAction:^(UIView *weakSelf) {
        //动画核心编程
        //keyPath bounds.size
            JHKeyframeAnimation *sizeAnimation = [weakSelf basicAnimationForKeyPath:@"bounds.size"];
            sizeAnimation.fromValue = [NSValue valueWithCGSize:weakSelf.layer.bounds.size];
            sizeAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(width, height)];
            //加入动画数组
            [weakSelf addAnimationFromCalculationBlock:sizeAnimation];
        }];
        //执行完了的结果添加到当前的Layer上,不然会返回初始状态
        [self addAnimationCompletionAction:^(UIView *weakSelf) {
            CGRect bounds = CGRectMake(0, 0, width, height);
            weakSelf.layer.bounds = bounds;
            weakSelf.bounds = bounds;
        }];
        //返回当前对象,可以链式调用
        return self;
    };
    return chainable;
}

把动画加入到动画数组

-(void) addAnimationCalculationAction:(JHAnimationCalculationAction)action {
    NSMutableArray *actions = [self.JHAnimationCalculationActions lastObject];
    [actions addObject:action];
}

把动画结果加入到结果的数组中

-(void) addAnimationCompletionAction:(JHAnimationCompletionAction)action {
    NSMutableArray *actions = [self.JHAnimationCompletionActions lastObject];
    [actions addObject:action];
}

JHAnimationCalculationActions通过关联把数组设置为当前对象的属性 其他数组一样。

如何调用的呢?

比如:self.myView.moveX(50).animate(.25);通过moveX 把动画 过程添加到动画数组,之后通过animate 调用,把动画添加到 CAAnimationGroup对象中,然后,再加入到当前的layer

-(JHChainableAnimation)animate {
    JHChainableAnimation chainable = JHChainableAnimation(duration) {
        //从 CAAnimationGroup 数组中拿出最后一个CAAnimationGroup对象
        CAAnimationGroup *group = [self.JHAnimationGroups lastObject];
        //设置动画需要的时间
        group.duration = duration;
        [self animateChain];

        return self;
    };
    return chainable;
}

-(void) animateChain {
    [self sanityCheck];
    //提交事务
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    [CATransaction setCompletionBlock:^{ //一组动画完成之后的事情
        [self.layer removeAnimationForKey:@"AnimationChain"];
        [self chainLinkDidFinishAnimating];
    }];
    //执行动画
    [self animateChainLink];

    [CATransaction commit];

    [self executeCompletionActions];
}

-(void) animateChainLink {
    [self makeAnchorFromX:0.5 Y:0.5];
    //动画过程传入参数
    NSMutableArray *actionCluster = [self.JHAnimationCalculationActions firstObject];
    for (JHAnimationCalculationAction action in actionCluster) {
    //防止循环引用
        __weak UIView *weakSelf = self;
        action(weakSelf);
    }
    CAAnimationGroup *group = [self.JHAnimationGroups firstObject];
    NSMutableArray *animationCluster = [self.JHAnimations firstObject];
    for (JHKeyframeAnimation *animation in animationCluster) {
        animation.duration = group.duration;
        [animation calculate];
    }
    //把一组动画加入到CAAnimationGroup 来
    group.animations = animationCluster;
    //添加动画
    [self.layer addAnimation:group forKey:@"AnimationChain"];

    // 自动布局属性的
    NSTimeInterval delay = MAX(group.beginTime - CACurrentMediaTime(), 0.0);
    [self.class animateWithDuration:group.duration
                              delay:delay
                            options:0
                         animations:^{
        [self updateConstraints];
    } completion:nil];
}

执行过程大概就是这样子!睡了,明天有空继续分析。分析完这个库,核心动画编程会了一大半了。

内容概要:本文档详细介绍了Analog Devices公司生产的AD8436真均方根-直流(RMS-to-DC)转换器的技术细节及其应用场景。AD8436由三个独立模块构成:轨到轨FET输入放大器、高动态范围均方根计算内核和精密轨到轨输出放大器。该器件不仅体积小巧、功耗低,而且具有广泛的输入电压范围和快速响应特性。文档涵盖了AD8436的工作原理、配置选项、外部组件选择(如电容)、增益调节、单电源供电、电流互感器配置、接地故障检测、三相电源监测等方面的内容。此外,还特别强调了PCB设计注意事项和误差源分析,旨在帮助工程师更好地理解和应用这款高性能的RMS-DC转换器。 适合人群:从事模拟电路设计的专业工程师和技术人员,尤其是那些需要精确测量交流电信号均方根值的应用开发者。 使用场景及目标:①用于工业自动化、医疗设备、电力监控等领域,实现对交流电压或电流的精准测量;②适用于手持式数字万用表及其他便携式仪器仪表,提供高效的单电源解决方案;③在电流互感器配置中,用于检测微小的电流变化,保障电气安全;④应用于三相电力系统监控,优化建立时间和转换精度。 其他说明:为了确保最佳性能,文档推荐使用高质量的电容器件,并给出了详细的PCB布局指导。同时提醒用户关注电介质吸收和泄漏电流等因素对测量准确性的影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值