简单的仿高德首页,上拖页面跟随效果 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]; }
码云源码: