今天用百度外卖,看到百度外卖app有一个下拉形变的效果,觉得挺有意思的,于是自己动手写了一下。
首先说一下我的思路,我创建了一个UITableView和一个显示形变的视图View(自定义的),两者同一个父视图,都加载控制的View上,首先形变视图高度为0,tableView占据整个View,使用KVO监听tableView的contentOffset属性值变化,让形变视图的高度 为MAX(0, -offPoint.y);offPoint为contentOffset属性值。所以当tableView下拉的时候,高度发生了变化,导致的结果就是形变视图紧靠tableView,当改变形变视图的高度时,形变视图将发生改变。
以下为自定义的形变视图:
EllipseShadeView.h文件
#define EllipseShadeMaxHight 150
#import@interface EllipseShadeView : UIView
@property(nonatomic,weak)CAShapeLayer *ellipseShadeLayer;
@property(nonatomic,assign)CGFloat hight;
//重新hight的方法,当hight改变时候,需要修改视图形状
-(void)setHight:(CGFloat)hight;
@end
EllipseShadeView.m
#import "EllipseShadeView.h"
@implementation EllipseShadeView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
self.backgroundColor = [UIColor whiteColor];
self.hight = frame.size.height;
[self setHight:frame.size.height];
}
return self;
}
-(void)createEllipseShadeLayer
{
CAShapeLayer *layer = [CAShapeLayer layer];
layer.fillColor = [UIColor purpleColor].CGColor;
layer.strokeColor = [UIColor purpleColor].CGColor;
layer.frame = self.bounds;
[self.layer addSublayer:layer];
_ellipseShadeLayer = layer;
}
-(void)setHight:(CGFloat)hight
{
_hight = hight;
CGRect rect = self.frame;
rect.size.height = _hight;
self.frame = rect;
//重绘
[self setNeedsDisplay];
}
-(void)drawRect:(CGRect)rect
{
if (!_ellipseShadeLayer)
{
[self createEllipseShadeLayer];
}
if (_hight > 0 )
{
_ellipseShadeLayer.fillColor = [UIColor purpleColor].CGColor;
}
else
{
_ellipseShadeLayer.fillColor = [UIColor clearColor].CGColor;
}
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(0, 0)];
CGFloat realHight = MIN(EllipseShadeMaxHight, self.bounds.size.height);
CGFloat controlPointY = realHight * (IPHONE_HEIGHT / 2) / EllipseShadeMaxHight;
[path addQuadCurveToPoint:CGPointMake(self.bounds.size.width, 0) controlPoint:CGPointMake(IPHONE_WIDTH / 2, controlPointY)];
_ellipseShadeLayer.path = path.CGPath;
}
@end
#pragma mark---监听tableView的contentOffset变化,改变_ellipseView高度---
[_tableView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil];
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSValue *newValue = change[@"new"];
CGPoint offPoint = [newValue CGPointValue];
CGFloat hight = MAX(0, -offPoint.y);
_ellipseView.hight = hight;
}
运行截图如下:
尼玛,话说今天是光棍节,唉!!!