From 7b02207537d35bfa1714bf8beafc921f717d100a Mon Sep 17 00:00:00 2001 From: 单军华 Date: Wed, 11 Jul 2018 10:47:42 +0800 Subject: [PATCH] 首次上传 --- screendisplay/Pods/M13ProgressSuite/Classes/ProgressViews/M13ProgressViewLetterpress.m | 300 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 300 insertions(+), 0 deletions(-) diff --git a/screendisplay/Pods/M13ProgressSuite/Classes/ProgressViews/M13ProgressViewLetterpress.m b/screendisplay/Pods/M13ProgressSuite/Classes/ProgressViews/M13ProgressViewLetterpress.m new file mode 100755 index 0000000..aeaf40d --- /dev/null +++ b/screendisplay/Pods/M13ProgressSuite/Classes/ProgressViews/M13ProgressViewLetterpress.m @@ -0,0 +1,300 @@ +// +// M13ProgressViewLetterpress.m +// M13ProgressSuite +// +// Created by Brandon McQuilkin on 4/28/14. +// Copyright (c) 2014 Brandon McQuilkin. All rights reserved. +// + +#import "M13ProgressViewLetterpress.h" + +@interface LetterpressView : UIView + +@property (nonatomic, strong) M13ProgressViewLetterpress *progressView; +@property (nonatomic, assign) CGRect drawRect; + +@end + +@interface M13ProgressViewLetterpress () + +/**The start progress for the progress animation.*/ +@property (nonatomic, assign) CGFloat animationFromValue; +/**The end progress for the progress animation.*/ +@property (nonatomic, assign) CGFloat animationToValue; +/**The start time interval for the animaiton.*/ +@property (nonatomic, assign) CFTimeInterval animationStartTime; +/**Link to the display to keep animations in sync.*/ +@property (nonatomic, strong) CADisplayLink *displayLink; +/** + The display link that controls the spring animation. + */ +@property (nonatomic, strong) CADisplayLink *springDisplayLink; + +@end + +@implementation M13ProgressViewLetterpress +{ + CGFloat rotation; + CGFloat restRotation; + CGFloat velocity; + LetterpressView *letterpressView; +} + +- (id)init +{ + self = [super init]; + if (self) { + [self setup]; + } + return self; +} + +- (id)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self setup]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self setup]; + } + return self; +} + +- (void)dealloc +{ + [_springDisplayLink invalidate]; +} + +- (void)setup +{ + //Set defauts + self.animationDuration = 1.0; + _numberOfGridPoints = CGPointMake(3, 3); + _notchSize = CGSizeMake(1, 1); + _pointShape = M13ProgressViewLetterpressPointShapeCircle; + _pointSpacing = 0.0; + + rotation = 0; + restRotation = 0; + _springConstant = 200; + _dampingCoefficient = 15; + _mass = 1; + velocity = 0; + + //Set default colors + self.primaryColor = [UIColor colorWithRed:0 green:122/255.0 blue:1.0 alpha:1.0]; + self.secondaryColor = [UIColor colorWithRed:181/255.0 green:182/255.0 blue:183/255.0 alpha:1.0]; + + //Draw and animate a sublayer, since autolayout does not like CATransforms. + letterpressView = [[LetterpressView alloc] init]; + letterpressView.backgroundColor = [UIColor clearColor]; + letterpressView.progressView = self; + [self setFrame:self.frame]; + + [self addSubview:letterpressView]; + + //Set own background color + self.backgroundColor = [UIColor clearColor]; + self.clipsToBounds = NO; + + //Setup the display link for rotation + _springDisplayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(rotateWithDisplayLink:)]; + [_springDisplayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:(id)kCFRunLoopCommonModes]; + +} + +- (void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + //Need to inset the layer since we don't want the corner's cliped + CGFloat radius = MIN(self.frame.size.width, self.frame.size.height); + CGFloat size = radius / sqrtf(2.0); + letterpressView.drawRect = CGRectIntegral(CGRectMake((self.frame.size.width - size) / 2.0, (self.frame.size.height - size) / 2.0, size, size)); + letterpressView.frame = CGRectIntegral(CGRectMake((self.frame.size.width - size) / 2.0, (self.frame.size.height - size) / 2.0, size, size)); +} + +- (void)setNeedsDisplay +{ + [super setNeedsDisplay]; + [letterpressView setNeedsDisplay]; +} + +- (CGSize)intrinsicContentSize +{ + //Everything is based on scale. No minimum size. + return CGSizeMake(UIViewNoIntrinsicMetric, UIViewNoIntrinsicMetric); +} + +#pragma mark - Properties + +- (void)setNumberOfGridPoints:(CGPoint)numberOfGridPoints +{ + _numberOfGridPoints = numberOfGridPoints; + [self setNeedsDisplay]; +} + +- (void)setPointShape:(M13ProgressViewLetterpressPointShape)pointShape +{ + _pointShape = pointShape; + [self setNeedsDisplay]; +} + +- (void)setPointSpacing:(CGFloat)pointSpacing +{ + if (pointSpacing > 1) { + pointSpacing = 1; + } else if (pointSpacing < 0) { + pointSpacing = 0; + } + _pointSpacing = pointSpacing; + [self setNeedsDisplay]; +} + +- (void)setNotchSize:(CGSize)notchSize +{ + _notchSize = notchSize; + [self setNeedsDisplay]; +} + +#pragma mark - Animation + +- (void)setProgress:(CGFloat)progress animated:(BOOL)animated +{ + if (animated == NO) { + if (_displayLink) { + //Kill running animations + [_displayLink invalidate]; + _displayLink = nil; + } + [super setProgress:progress animated:NO]; + [self setNeedsDisplay]; + } else { + _animationStartTime = CACurrentMediaTime(); + _animationFromValue = self.progress; + _animationToValue = progress; + if (!_displayLink) { + //Create and setup the display link + [self.displayLink invalidate]; + self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(animateProgress:)]; + [self.displayLink addToRunLoop:NSRunLoop.mainRunLoop forMode:NSRunLoopCommonModes]; + } /*else { + //Reuse the current display link + }*/ + } +} + +- (void)animateProgress:(CADisplayLink *)displayLink +{ + dispatch_async(dispatch_get_main_queue(), ^{ + CGFloat dt = (displayLink.timestamp - self.animationStartTime) / self.animationDuration; + if (dt >= 1.0) { + //Order is important! Otherwise concurrency will cause errors, because setProgress: will detect an animation in progress and try to stop it by itself. Once over one, set to actual progress amount. Animation is over. + [self.displayLink invalidate]; + self.displayLink = nil; + [super setProgress:self.animationToValue animated:NO]; + [self setNeedsDisplay]; + return; + } + + //Set progress + [super setProgress:self.animationFromValue + dt * (self.animationToValue - self.animationFromValue) animated:YES]; + [self setNeedsDisplay]; + + }); +} + +- (void)rotateWithDisplayLink:(CADisplayLink *)displayLink +{ + //Take account for lag + for (int i = 0; i < displayLink.frameInterval; i++){ + + //Calculate the new angle + CGFloat displacement = rotation - restRotation; + CGFloat kx = _springConstant * displacement; + CGFloat bv = _dampingCoefficient * velocity; + CGFloat acceleration = (kx + bv) / _mass; + + velocity -= (acceleration * displayLink.duration); + rotation += (velocity * displayLink.duration); + + //Set the angle + [letterpressView setTransform:CGAffineTransformMakeRotation(rotation * M_PI / 180)]; + + UIView *view = [[self subviews] lastObject]; + [view setTransform:CGAffineTransformMakeRotation(rotation * M_PI / 180)]; + + //If we are slowing down, animate to a new angle. + if (fabs(velocity) < 1) { + restRotation += (arc4random() & 2 ? 90 : -90); + } + } +} + +@end + +@implementation LetterpressView + +#pragma mark - Drawing + +- (void)drawRect:(CGRect)rect +{ + CGContextRef ctx = UIGraphicsGetCurrentContext(); + + //Calculate the corners of the square of the points that we will not draw + CGPoint ignoreTopLeft = CGPointMake((_progressView.numberOfGridPoints.x - _progressView.notchSize.width) / 2, 0); + CGPoint ignoreBottomRight = CGPointMake(_progressView.numberOfGridPoints.x - ((_progressView.numberOfGridPoints.x - _progressView.notchSize.width) / 2), (_progressView.numberOfGridPoints.y - _progressView.notchSize.height) / 2); + //Calculate the point size + CGSize pointSize = CGSizeMake(_drawRect.size.width / _progressView.numberOfGridPoints.x, _drawRect.size.height / _progressView.numberOfGridPoints.y); + + //Setup + CGRect pointRect = CGRectZero; + int index = -1; + int indexToFillTo = (int)(_progressView.numberOfGridPoints.x * _progressView.numberOfGridPoints.y * _progressView.progress); + + //Draw + for (int y = (int)_progressView.numberOfGridPoints.y - 1; y >= 0; y--) { + for (int x = 0; x < _progressView.numberOfGridPoints.x; x++) { + + index += 1; + + //Are we in a forbidden zone + if (x >= ignoreTopLeft.x && x < ignoreBottomRight.x && y >= ignoreTopLeft.y && y < ignoreBottomRight.y) { + //Move to the next point + continue; + } + + //Calculat the rect of the point + pointRect.size = pointSize; + pointRect.origin = CGPointMake(pointSize.width * x, pointSize.height * y); + pointRect = CGRectInset(pointRect, pointSize.width * _progressView.pointSpacing, pointSize.height * _progressView.pointSpacing); + + //Set the fill color + if (index < indexToFillTo) { + CGContextSetFillColorWithColor(ctx, _progressView.primaryColor.CGColor); + } else { + CGContextSetFillColorWithColor(ctx, _progressView.secondaryColor.CGColor); + } + + //Draw the shape + if (_progressView.pointShape == M13ProgressViewLetterpressPointShapeSquare) { + CGContextFillRect(ctx, pointRect); + } else if (_progressView.pointShape == M13ProgressViewLetterpressPointShapeCircle) { + UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:pointRect cornerRadius:(pointRect.size.width / 2.0)]; + CGContextBeginPath(ctx); + CGContextAddPath(ctx, path.CGPath); + CGContextFillPath(ctx); + } + } + } +} + + + +@end -- Gitblit v1.8.0