仿QQ音乐播放弹出界面, 向下滑动收回, 向上滑动弹起

仿QQ音乐播放弹出界面, 向下滑动收回, 向上滑动弹起

先看效果

demo github地址
效果图

滑动收回&弹起逻辑

  1.当向下滑动速度过快会收回
  2.当向上滑动速度过快会弹起
  3.当滑动offstSetY > 屏幕高度一半就会收回,
  4.当滑动offstSetY < 屏幕高度一半就会弹起
  我们需要利用系统的类UIPanGestureRecognizer完成

重要提示

CGPoint speed = [panGes velocityInView:panGes.view];
speed 手势是滑动速度
   当speed.y > 600 就认为用户想要收回界面
   当speed.y < -600 就认为用户想要弹出界面

使用

在控制器中使用, 导入SlideView类

// 点击按钮弹出
- (void)popBtnUpClick {
    [self.slideView popUpWithDuration:0.3];
}

- (SlideView *)slideView {
    if (!_slideView) {
        // 注意, 默认在屏幕以下布局
        _slideView = [[SlideView alloc] initWithFrame:CGRectMake(0, kScreenHeight, kScreenWidth, kScreenHeight)];
    }
    return _slideView;
}

SlideView类编码

创建一个SlideView类继承UIView

SlideView.h
@interface SlideView : UIView
/// 弹出
/// @param duration 弹出动画时长
- (void)popUpWithDuration:(NSTimeInterval)duration;
/// 收回
/// @param duration 收回动画时长
- (void)takeBackWithDuration:(NSTimeInterval)duration;

@end
SlideView.m
//
//  SlideView.m
//  UI_Demo
//  Created by nyl on 2020/3/19.
//  Copyright © 2020 nieyinlong. All rights reserved.
//

#import "SlideView.h"

@interface SlideView()

@property (nonatomic, strong) UIButton *btn;

@end

@implementation SlideView

- (instancetype)initWithFrame:(CGRect)frame {
    if (self = [super initWithFrame:frame]) {
        [self initView];
        
        UIPanGestureRecognizer *ges = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGes:)];
        [self addGestureRecognizer:ges];
    }
    return self;
}

- (void)initView {
    
    self.backgroundColor = [UIColor grayColor];
    
    _btn = [UIButton buttonWithType:(UIButtonTypeSystem)];
    [_btn setTitle:@"收回⇓" forState:(UIControlStateNormal)];
    [_btn setBackgroundColor:[UIColor whiteColor]];
    [_btn addTarget:self action:@selector(hideClick) forControlEvents:(UIControlEventTouchUpInside)];
    [self addSubview:_btn];
    
    [_btn mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(90);
        make.left.mas_equalTo(24);
    }];
    
    // TODO: 继续布局你想要的界面
}

- (void)handlePanGes:(UIPanGestureRecognizer *)panGes {
    if (panGes.state == UIGestureRecognizerStateChanged) {
        CGPoint location = [panGes locationInView:self];
        if (location.y < 0 || location.y > self.bounds.size.height) {
            return;
        }
        CGPoint translation = [panGes translationInView:self];
        NSLog(@"当前视图在View的位置:%@----平移位置:%@",NSStringFromCGPoint(location),NSStringFromCGPoint(translation));
        //panGes.view.center = CGPointMake(recognizer.view.center.x + translation.x,recognizer.view.center.y + translation.y);
        // 这里kScreenWidth / 2 写死, 就一直靠左
        panGes.view.center = CGPointMake(kScreenWidth / 2, panGes.view.center.y + translation.y);
        [panGes setTranslation:CGPointZero inView:self];
    }
    else if (panGes.state == UIGestureRecognizerStateEnded || panGes.state == UIGestureRecognizerStateCancelled) {
        CGPoint speed = [panGes velocityInView:panGes.view];
        NSLog(@"滑动速度:%@", NSStringFromCGPoint(speed));
        if (speed.y > 600) {
            [self takeBackWithDuration:0.1];
        } else if(speed.y < -600) {
            [self popUpWithDuration:0.1];
        }
        if (self.frame.origin.y > kScreenHeight / 2) {
            [self takeBackWithDuration:0.3];
        } else {
            [self popUpWithDuration:0.3];
        }
    }
}

- (void)popUpWithDuration:(NSTimeInterval)duration {
    if (!self.superview) {
        // 加在window上
        [[UIApplication sharedApplication].delegate.window addSubview:self];
    }
    CGRect frame = self.frame;
      frame.origin.y = 0;
      [UIView animateWithDuration:duration animations:^{
          self.frame = frame;
      }];
}

- (void)takeBackWithDuration:(NSTimeInterval)duration {
    CGRect frame = self.frame;
    frame.origin.y = kScreenHeight;
    [UIView animateWithDuration:duration animations:^{
        self.frame = frame;
    }];
}

- (void)hideClick {
    [self takeBackWithDuration:0.3];
}

@end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值