iOS开发下拉导航栏果冻效果

本文介绍使用UIBezierPath实现动态果冻效果的过程。通过拖动屏幕上的红点,可以改变果冻形状,并且该效果适用于多种场景。文章提供了一个完整的iOS应用示例,包括手势识别、路径绘制等关键技术。

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

在简书上看到别人写的用UIBezierPath实现果冻效果感觉效果很棒,抽时间进行了代码仿写,精简了一些东西添加了少许自己的注释,记录下来以便日后回忆,也希望对大家有所帮助。

#define MIN_HEIGHT 100

@interface ViewController ()

@property(strong,readwrite,nonatomic)CAShapeLayer *shapeLayer;//形变视图

@property(assign,readwrite,nonatomic)float curveX;//拖动红点x坐标
@property(assign,readwrite,nonatomic)float curveY;//拖动红点y坐标
@property(strong,readwrite,nonatomic)UIView *curveView;//拖动红点


@property(assign,readwrite,nonatomic)float mHeight;//手势移动相对高度

@property(strong,readwrite,nonatomic)CADisplayLink *displayLink;
@end
复制代码
@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   
    //初始化形变视图
    _shapeLayer=[CAShapeLayer layer];
    _shapeLayer.fillColor=[UIColor colorWithRed:0.2 green:0.2 blue:0.2 alpha:1].CGColor;
    [self.view.layer addSublayer:_shapeLayer];
    
    
    //初始化拖动点
    _curveX=self.view.frame.size.width/2;
    _curveY=MIN_HEIGHT;
    _curveView=[[UIView alloc]initWithFrame:CGRectMake(_curveX, _curveY, 3, 3)];
    _curveView.backgroundColor=[UIColor redColor];
    [self.view addSubview:_curveView];
    
    
    _mHeight=100;
    //添加手势
    UIPanGestureRecognizer *pan=[[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGestureAction:)];
    self.view.userInteractionEnabled=YES;
    [self.view addGestureRecognizer:pan];
    
    //开启循环
    _displayLink=[CADisplayLink displayLinkWithTarget:self selector:@selector(calculatePath)];
    [_displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
    _displayLink.paused=YES;
    
    [self updateShapeLayerPath];
}
复制代码
-(void)panGestureAction:(UIPanGestureRecognizer *)pan
{
    if (pan.state==UIGestureRecognizerStateChanged) {
        
        CGPoint point=[pan translationInView:self.view];
        
        _mHeight=point.y*0.7+MIN_HEIGHT;//乘0.7可以使拖动效果更好
        _curveX=self.view.frame.size.width/2+point.x;
        _curveY=_mHeight>MIN_HEIGHT?_mHeight:MIN_HEIGHT;
        _curveView.frame=CGRectMake(_curveX, _curveY, 3, 3);
        
        [self updateShapeLayerPath];
        
    }
    else if (pan.state==UIGestureRecognizerStateEnded)
    {
       _displayLink.paused = NO;
        
        [UIView animateWithDuration:1.0
                              delay:0.0
             usingSpringWithDamping:0.5
              initialSpringVelocity:1
                            options:UIViewAnimationOptionCurveEaseInOut
                         animations:^{
                             
                             _curveView.frame = CGRectMake(self.view.frame.size.width/2.0, MIN_HEIGHT, 3, 3);//拖动结束红点恢复原来位置
                             
                         } completion:^(BOOL finished) {
                             
                             if(finished)
                             {
                                 _displayLink.paused = YES;
                             }
                             
                         }];
        
    
    }


}
复制代码

拖动结束根据_curveView.frame恢复原位置帧动画,计算导航形状

-(void)calculatePath
{
    _curveX=_curveView.center.x;
    _curveY=_curveView.center.y;
    [self updateShapeLayerPath];


}
复制代码

更新导航栏贝塞尔曲线

-(void)updateShapeLayerPath
{
    UIBezierPath *path=[UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(0, 0)];
    [path addLineToPoint:CGPointMake(self.view.frame.size.width, 0)];
    [path addLineToPoint:CGPointMake(self.view.frame.size.width, MIN_HEIGHT)];
    [path addQuadCurveToPoint:CGPointMake(0, MIN_HEIGHT) controlPoint:CGPointMake(_curveX, _curveY)];
    [path closePath];
    
    _shapeLayer.path=path.CGPath;
    
}



@end
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值