周末仿写了半糖的下拉刷新,学了两句法语
C’est La Vie
La Vie est belle
C’est La Vie 通常是用在较为消极的事情发生时,用于自我安慰或自我解嘲,鼓励自己或他人即使遇到了再大的难处,也要坦然笑对生活。鸡汤一下,开始正文。
示例
思路 PDPullToRefresh是给UIScrollView加的分类,包括PDHeaderRefreshView和PDFooterRefreshView ,整个刷新过程可分为两部分
下拉时 - C’est La Vie 动画
刷新时 - La Vie est belle 动画
C’est La Vie 动画 首先得拿到C’est La Vie的字形,这里用到了CoreText,拿到字形后添加到layer.path上显示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 CGMutablePathRef letters = CGPathCreateMutable (); CTFontRef font = CTFontCreateWithName(CFSTR ("HelveticaNeue-UltraLight" ), pFontSize, NULL ); NSDictionary *attrs = [NSDictionary dictionaryWithObjectsAndKeys: (__bridge id )font, kCTFontAttributeName, nil ]; NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:animationString attributes:attrs]; CTLineRef line = CTLineCreateWithAttributedString((CFAttributedStringRef )attrString); CFArrayRef runArray = CTLineGetGlyphRuns(line); for (CFIndex runIndex = 0 ; runIndex < CFArrayGetCount (runArray); runIndex++) { CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex (runArray, runIndex); CTFontRef runFont = CFDictionaryGetValue (CTRunGetAttributes(run), kCTFontAttributeName); for (CFIndex runGlyphIndex = 0 ; runGlyphIndex < CTRunGetGlyphCount(run); runGlyphIndex++) { CFRange thisGlyphRange = CFRangeMake (runGlyphIndex, 1 ); CGGlyph glyph; CGPoint position; CTRunGetGlyphs(run, thisGlyphRange, &glyph); CTRunGetPositions(run, thisGlyphRange, &position); { CGPathRef letter = CTFontCreatePathForGlyph(runFont, glyph, NULL ); CGAffineTransform t = CGAffineTransformMakeTranslation (position.x , position.y ); CGPathAddPath (letters, &t, letter); CGPathRelease (letter); } } } CFRelease (line); UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointZero ]; [path appendPath:[UIBezierPath bezierPathWithCGPath :letters]]; CGPathRelease (letters); CFRelease (font); CAShapeLayer *pathLayer = [CAShapeLayer layer]; pathLayer.frame = self .animationLayer .bounds ; pathLayer.bounds = CGPathGetBoundingBox (path.CGPath ); pathLayer.geometryFlipped = YES ; pathLayer.path = path.CGPath ; pathLayer.strokeColor = [UIColor colorWithRed:234.0 /255 green:84.0 /255 blue:87.0 /255 alpha:1 ].CGColor ; pathLayer.fillColor = nil ; pathLayer.lineWidth = 1.0 f; pathLayer.lineJoin = kCALineJoinBevel ;
然后用KVO监听ScrollView的contentOffset属性,与pathLayer的strokeEnd关联起来,C’est La Vie就可以随着下拉做动画啦。
La Vie est belle 动画 La Vie est belle与C’est La Vie的动画不同,它是一直闪动着的,还是先拿到La Vie est belle的字形,这里用CAGradientLayer可以方便的处理颜色渐变。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CAGradientLayer *gradientLayer = (CAGradientLayer *)self .gradientLayer ; if ([gradientLayer animationForKey:kAnimationKey] == nil ) { CABasicAnimation *startPointAnimation = [CABasicAnimation animationWithKeyPath:gradientStartPointKey]; startPointAnimation.toValue = [NSValue valueWithCGPoint :CGPointMake (1.0 , 0 )]; startPointAnimation.timingFunction = [CAMediaTimingFunction functionWithName:_animationPacing]; CABasicAnimation *endPointAnimation = [CABasicAnimation animationWithKeyPath:gradientEndPointKey]; endPointAnimation.toValue = [NSValue valueWithCGPoint :CGPointMake (1 + pHaloWidth, 0 )]; endPointAnimation.timingFunction = [CAMediaTimingFunction functionWithName:_animationPacing]; CAAnimationGroup *group = [CAAnimationGroup animation]; group.animations = @[startPointAnimation, endPointAnimation]; group.duration = pHaloDuration; group.timingFunction = [CAMediaTimingFunction functionWithName:_animationPacing]; group.repeatCount = HUGE_VALF; [gradientLayer addAnimation:group forKey:kAnimationKey]; }
使用 安装
添加 pod 'PDPullToRefresh'
到你的 Podfile ,然后pod install
。
手动添加到你的Xcode项目中,#import "PDPullToRefresh.h"
。
添加下拉刷新 1 2 3 4 [tableView pd_addHeaderRefreshWithNavigationBar: YES andActionHandler: ^{ }];
添加上拉刷新 1 2 3 4 [tableView pd_addFooterRefreshWithNavigationBar: YES andActionHandler: ^{ }];
立即刷新 1 [tableView.pdHeaderRefreshView startRefreshing]
自定义 目前仅支持下拉距离自定义,默认高度为80
1 2 @property (nonatomic , assign ) CGFloat pdHeaderRefreshViewHeight;@property (nonatomic , assign ) CGFloat pdFooterRefreshViewHeight;
最后 附上Github地址 ,外加感谢半糖 、SVPullToRefresh 对我的启发。