热更新demo

IFTTTInterpolatable.m 9.2KB

    // // IFTTTInterpolatable.m // JazzHands // // Created by Laura Skelton on 6/17/15. // Copyright (c) 2015 IFTTT Inc. All rights reserved. // #import "IFTTTInterpolatable.h" #pragma mark - NSNumber (IFTTTInterpolatable) @implementation NSNumber (IFTTTInterpolatable) - (NSNumber *)interpolateTo:(NSNumber *)toValue withProgress:(CGFloat)progress { if (strcmp([self objCType], @encode(char)) == 0) { if (!(strcmp([toValue objCType], @encode(char)) == 0)) return self; return (progress == 0.f ? self : toValue); } return @([self.class interpolateCGFloatFrom:(CGFloat)[self floatValue] to:(CGFloat)[toValue floatValue] withProgress:progress]); } + (CGFloat)interpolateCGFloatFrom:(CGFloat)fromValue to:(CGFloat)toValue withProgress:(CGFloat)progress { CGFloat totalChange = toValue - fromValue; CGFloat currentChange = totalChange * progress; return fromValue + currentChange; } @end #pragma mark - UIColor (IFTTTInterpolatable) @implementation UIColor (IFTTTInterpolatable) - (UIColor *)interpolateTo:(UIColor *)toValue withProgress:(CGFloat)progress { CGFloat startRed, startBlue, startGreen, startAlpha; CGFloat endRed, endBlue, endGreen, endAlpha; UIColor *interpolatedColor = self; if ([self.class iftttGetRed:&startRed green:&startGreen blue:&startBlue alpha:&startAlpha fromColor:self] && [self.class iftttGetRed:&endRed green:&endGreen blue:&endBlue alpha:&endAlpha fromColor:toValue]) { CGFloat red = [NSNumber interpolateCGFloatFrom:startRed to:endRed withProgress:progress]; CGFloat green = [NSNumber interpolateCGFloatFrom:startGreen to:endGreen withProgress:progress]; CGFloat blue = [NSNumber interpolateCGFloatFrom:startBlue to:endBlue withProgress:progress]; CGFloat alpha = [NSNumber interpolateCGFloatFrom:startAlpha to:endAlpha withProgress:progress]; interpolatedColor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha]; } return interpolatedColor; } + (BOOL)iftttGetRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha fromColor:(UIColor *)color { CGFloat white; if ([color getRed:red green:green blue:blue alpha:alpha]) { return YES; } else if ([color getWhite:&white alpha:alpha]) { *red = white; *green = white; *blue = white; return YES; } return NO; } @end #pragma mark - NSValue (IFTTTInterpolatable) @implementation NSValue (IFTTTInterpolatable) - (NSValue *)interpolateTo:(NSValue *)toValue withProgress:(CGFloat)progress { if (strcmp([self objCType], @encode(CGPoint)) == 0) { if (!(strcmp([toValue objCType], @encode(CGPoint)) == 0)) return self; // CGPoint method CGPoint fromPoint = [self CGPointValue]; CGPoint toPoint = [toValue CGPointValue]; CGPoint pointBetween = [self.class interpolateCGPointFrom:fromPoint to:toPoint withProgress:progress]; return [NSValue valueWithCGPoint:pointBetween]; } else if (strcmp([self objCType], @encode(CGSize)) == 0) { if (!(strcmp([toValue objCType], @encode(CGSize)) == 0)) return self; // CGRect method CGSize fromSize = [self CGSizeValue]; CGSize toSize = [toValue CGSizeValue]; CGSize sizeBetween = [self.class interpolateCGSizeFrom:fromSize to:toSize withProgress:progress]; return [NSValue valueWithCGSize:sizeBetween]; } else if (strcmp([self objCType], @encode(CGRect)) == 0) { if (!(strcmp([toValue objCType], @encode(CGRect)) == 0)) return self; // CGRect method CGRect fromRect = [self CGRectValue]; CGRect toRect = [toValue CGRectValue]; CGRect rectBetween = [self.class interpolateCGRectFrom:fromRect to:toRect withProgress:progress]; return [NSValue valueWithCGRect:rectBetween]; } else if (strcmp([self objCType], @encode(CGVector)) == 0) { if (!(strcmp([toValue objCType], @encode(CGVector)) == 0)) return self; // CGVector method CGVector fromVector = [self CGVectorValue]; CGVector toVector = [toValue CGVectorValue]; CGVector vectorBetween = [self.class interpolateCGVectorFrom:fromVector to:toVector withProgress:progress]; return [NSValue valueWithCGVector:vectorBetween]; } else if (strcmp([self objCType], @encode(UIEdgeInsets)) == 0) { if (!(strcmp([toValue objCType], @encode(UIEdgeInsets)) == 0)) return self; // UIEdgeInsets method UIEdgeInsets fromInsets = [self UIEdgeInsetsValue]; UIEdgeInsets toInsets = [toValue UIEdgeInsetsValue]; UIEdgeInsets insetsBetween = [self.class interpolateUIEdgeInsetsFrom:fromInsets to:toInsets withProgress:progress]; return [NSValue valueWithUIEdgeInsets:insetsBetween]; } else if (strcmp([self objCType], @encode(UIOffset)) == 0) { if (!(strcmp([toValue objCType], @encode(UIOffset)) == 0)) return self; // UIOffset method UIOffset fromOffset = [self UIOffsetValue]; UIOffset toOffset = [toValue UIOffsetValue]; UIOffset offsetBetween = [self.class interpolateUIOffsetFrom:fromOffset to:toOffset withProgress:progress]; return [NSValue valueWithUIOffset:offsetBetween]; } else if (strcmp([self objCType], @encode(CGAffineTransform)) == 0) { if (!(strcmp([toValue objCType], @encode(CGAffineTransform)) == 0)) return self; // CGAffineTransform method CGAffineTransform fromTransform = [self CGAffineTransformValue]; CGAffineTransform toTransform = [toValue CGAffineTransformValue]; CGAffineTransform transformBetween = [self.class interpolateCGAffineTransformFrom:fromTransform to:toTransform withProgress:progress]; return [NSValue valueWithCGAffineTransform:transformBetween]; } return self; } + (CGPoint)interpolateCGPointFrom:(CGPoint)fromValue to:(CGPoint)toValue withProgress:(CGFloat)progress { CGFloat xBetween = [NSNumber interpolateCGFloatFrom:fromValue.x to:toValue.x withProgress:progress]; CGFloat yBetween = [NSNumber interpolateCGFloatFrom:fromValue.y to:toValue.y withProgress:progress]; return CGPointMake(xBetween, yBetween); } + (CGSize)interpolateCGSizeFrom:(CGSize)fromValue to:(CGSize)toValue withProgress:(CGFloat)progress { CGFloat widthBetween = [NSNumber interpolateCGFloatFrom:fromValue.width to:toValue.width withProgress:progress]; CGFloat heightBetween = [NSNumber interpolateCGFloatFrom:fromValue.height to:toValue.height withProgress:progress]; return CGSizeMake(widthBetween, heightBetween); } + (CGRect)interpolateCGRectFrom:(CGRect)fromValue to:(CGRect)toValue withProgress:(CGFloat)progress { CGPoint originBetween = [self interpolateCGPointFrom:fromValue.origin to:toValue.origin withProgress:progress]; CGSize sizeBetween = [self interpolateCGSizeFrom:fromValue.size to:toValue.size withProgress:progress]; return CGRectMake(originBetween.x, originBetween.y, sizeBetween.width, sizeBetween.height); } + (CGVector)interpolateCGVectorFrom:(CGVector)fromValue to:(CGVector)toValue withProgress:(CGFloat)progress { CGFloat dxBetween = [NSNumber interpolateCGFloatFrom:fromValue.dx to:toValue.dx withProgress:progress]; CGFloat dyBetween = [NSNumber interpolateCGFloatFrom:fromValue.dy to:toValue.dy withProgress:progress]; return CGVectorMake(dxBetween, dyBetween); } + (UIEdgeInsets)interpolateUIEdgeInsetsFrom:(UIEdgeInsets)fromValue to:(UIEdgeInsets)toValue withProgress:(CGFloat)progress { CGFloat topBetween = [NSNumber interpolateCGFloatFrom:fromValue.top to:toValue.top withProgress:progress]; CGFloat leftBetween = [NSNumber interpolateCGFloatFrom:fromValue.left to:toValue.left withProgress:progress]; CGFloat bottomBetween = [NSNumber interpolateCGFloatFrom:fromValue.bottom to:toValue.bottom withProgress:progress]; CGFloat rightBetween = [NSNumber interpolateCGFloatFrom:fromValue.right to:toValue.right withProgress:progress]; return UIEdgeInsetsMake(topBetween, leftBetween, bottomBetween, rightBetween); } + (UIOffset)interpolateUIOffsetFrom:(UIOffset)fromValue to:(UIOffset)toValue withProgress:(CGFloat)progress { CGFloat horizontalBetween = [NSNumber interpolateCGFloatFrom:fromValue.horizontal to:toValue.horizontal withProgress:progress]; CGFloat verticalBetween = [NSNumber interpolateCGFloatFrom:fromValue.vertical to:toValue.vertical withProgress:progress]; return UIOffsetMake(horizontalBetween, verticalBetween); } + (CGAffineTransform)interpolateCGAffineTransformFrom:(CGAffineTransform)fromValue to:(CGAffineTransform)toValue withProgress:(CGFloat)progress { CGFloat aBetween = [NSNumber interpolateCGFloatFrom:fromValue.a to:toValue.a withProgress:progress]; CGFloat bBetween = [NSNumber interpolateCGFloatFrom:fromValue.b to:toValue.b withProgress:progress]; CGFloat cBetween = [NSNumber interpolateCGFloatFrom:fromValue.c to:toValue.c withProgress:progress]; CGFloat dBetween = [NSNumber interpolateCGFloatFrom:fromValue.d to:toValue.d withProgress:progress]; CGFloat txBetween = [NSNumber interpolateCGFloatFrom:fromValue.tx to:toValue.tx withProgress:progress]; CGFloat tyBetween = [NSNumber interpolateCGFloatFrom:fromValue.ty to:toValue.ty withProgress:progress]; return CGAffineTransformMake(aBetween, bBetween, cBetween, dBetween, txBetween, tyBetween); } @end