简单的仿高德首页,上拖页面跟随效果 iOS

.h文件

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface TestView : UIView

@end

NS_ASSUME_NONNULL_END

.m文件

#import "UIView+Additions.h"
#import "TestView.h"
// 宽高
#define WIN_WIDTH  [[UIScreen mainScreen] bounds].size.width
#define WIN_HEIGHT [[UIScreen mainScreen] bounds].size.height
// 状态栏高度
#define STA_HEIGHT [[UIApplication sharedApplication] statusBarFrame].size.height
// 导航栏高度
#define NAV_HEIGHT (STA_HEIGHT + 44)
// 底部高度
 #define TABBAR_HEIGHT (STA_HEIGHT == 44 ? 83 : 49)

@interface TestView () <UIScrollViewDelegate>{
    CGFloat showH;
}
@property (nonatomic, assign) BOOL isTop;
@property (nonatomic, strong) UIView *leftView;
@property (nonatomic, strong) UIView *rightView;
@end
@implementation TestView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    [self setUI];
    return self;
}
- (void)setUI {
    
    showH = 62;
    self.layer.cornerRadius = 2;
    
    // 箭头
    UIView *topView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, WIN_WIDTH, showH)];
    [self addSubview:topView];
    topView.layer.cornerRadius = 4;
    
    CGFloat height = 5;
    CGFloat correction = height / 2;
    [topView addSubview:self.leftView];
    [topView addSubview:self.rightView];
    
    self.leftView.frame = CGRectMake((WIN_WIDTH - 30)*0.5, 8, 15 + correction, height);
    self.leftView.centerY = 8 + 2.5;
    self.leftView.layer.cornerRadius = MIN(self.leftView.width, self.leftView.height) / 2;

    self.rightView.frame = CGRectMake(WIN_WIDTH*0.5 - correction, 8, 15 + correction, height);
    self.rightView.centerY =  8 + 2.5;
    self.rightView.layer.cornerRadius = MIN(self.rightView.width, self.rightView.height) / 2;
    self.leftView.backgroundColor = [UIColor greenColor];
    self.rightView.backgroundColor = [UIColor greenColor];

    //
    UIPanGestureRecognizer * panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
                                                                                            action:@selector(doHandlePanAction:)];
    [self addGestureRecognizer:panGestureRecognizer];
    
}
#pragma mark - Getter

- (UIView *)leftView {
    if (!_leftView) {
        _leftView = [UIView new];
    }
    return _leftView;
}

- (UIView *)rightView {
    if (!_rightView) {
        _rightView = [UIView new];
    }
    return _rightView;
}
- (void)animate:(void (^)(void))animations {
    [UIView animateWithDuration:0.5 delay:0 usingSpringWithDamping:1 initialSpringVelocity:1 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseOut animations:animations completion:^(BOOL finished) {

    }];
}
- (void)setStyle:(int)style {
    
    switch (style) {
        case 0:{
            [self animate:^{
                self.leftView.transform = CGAffineTransformIdentity;
                self.rightView.transform = CGAffineTransformIdentity;
            }];
        }
            break;
        case 1: {
            CGFloat angle = 20 * M_PI / 180;
            [self animate:^{
                self.leftView.transform = CGAffineTransformMakeRotation(angle);
                self.rightView.transform = CGAffineTransformMakeRotation(-angle);
            }];
        }
            break;
    }
}




- (void) doHandlePanAction:(UIPanGestureRecognizer *)paramSender{
    CGPoint point = [paramSender translationInView:self];
    NSLog(@"%f,%f",point.x,point.y);
    self.top +=point.y;
    if (self.top < NAV_HEIGHT) {
        self.top = NAV_HEIGHT;
    }
    if (paramSender.state == UIGestureRecognizerStateChanged) {
          [self commitTranslation:[paramSender translationInView:self]];
    }
    if (paramSender.state == UIGestureRecognizerStateEnded || paramSender.state == UIGestureRecognizerStateCancelled) {

        if (!_isTop) {
            if (self.top < NAV_HEIGHT*2) {
                [self initDataAndGoTop];
                NSLog(@"下滑goTop-%f",self.top);
            }else{
                [self goBack];
                NSLog(@"下滑goBack-%f",self.top);
            }
        }else{
            if (self.top > WIN_HEIGHT - NAV_HEIGHT*3) {
                [self goBack];
                NSLog(@"上滑goBack-%f",self.top);
            }else{
                [self initDataAndGoTop];
                NSLog(@"上滑goTop-%f",self.top);
            }
        }
    }else{
        NSLog(@"滑动中...");
        float bili = (self.top - NAV_HEIGHT ) / (WIN_HEIGHT - NAV_HEIGHT -TABBAR_HEIGHT - showH)*2;
        bili = bili > 1 ? 1 : bili;
    }
    //
    [paramSender setTranslation:CGPointMake(0, 0) inView:self];
}

- (void)initDataAndGoTop {
    [self goTop];
}


- (void) goTop {
    [UIView animateWithDuration:0.5 animations:^{
        self.top = NAV_HEIGHT;
    }completion:^(BOOL finished) {
       

    }];
    NSLog(@"-setStyle:1");
    [self setStyle:1];
}

- (void) goBack {
   
    [UIView animateWithDuration:0.5 animations:^{
        self.top = WIN_HEIGHT - TABBAR_HEIGHT - showH;
    }completion:^(BOOL finished) {
        
    }];
    NSLog(@"-setStyle:0");
    [self setStyle:0];
}

- (void)commitTranslation:(CGPoint)translation
{

    CGFloat absX = fabs(translation.x);
    CGFloat absY = fabs(translation.y);
    // 设置滑动有效距离
    if (MAX(absX, absY) < 10)
        return;
    if (absX > absY ) {
        if (translation.x<0) {
            //向左滑动
        }else{
            //向右滑动
        }
    } else if (absY > absX) {
        if (translation.y<0) {
            _isTop = YES;
            NSLog(@"向上滑动");
            //向上滑动
        }else{
            _isTop = NO;
            NSLog(@"向下滑动");
            //向下滑动
        }
    }
}

@end

把这个test控件添加到控制器中

#import "ViewController.h"
#import "TestView.h"
#import "UIView+Additions.h"
// 宽高
#define WIN_WIDTH  [[UIScreen mainScreen] bounds].size.width
#define WIN_HEIGHT [[UIScreen mainScreen] bounds].size.height
// 状态栏高度
#define STA_HEIGHT [[UIApplication sharedApplication] statusBarFrame].size.height
// 导航栏高度
#define NAV_HEIGHT (STA_HEIGHT + 44)
// 底部高度
 #define TABBAR_HEIGHT (STA_HEIGHT == 44 ? 83 : 49)

@interface ViewController ()
@property (nonatomic,strong) TestView *vTestView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor grayColor];
    
    _vTestView = [[TestView alloc]initWithFrame:CGRectMake(0, WIN_HEIGHT - 62 - TABBAR_HEIGHT, WIN_WIDTH, WIN_HEIGHT - NAV_HEIGHT - TABBAR_HEIGHT)];
    _vTestView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:_vTestView];
}

码云源码:

https://gitee.com/lijunchengit/dragPageFollowEffect

原文地址:https://www.cnblogs.com/ljcgood66/p/14686195.html