一、介绍:
在前面已经介绍了一种条件悬浮框,使用的是tableView的Plain分组样式实现的,因为这是tableView本身就具备的功能,分组悬浮效果。这次我来介绍第二种更加简单的方法,采用两个ScrollView来实现。
二、实现技术:
(1)两个ScrollView,一个是左右滚动,成为内容视图,另一个是上下滚动,作为容器视图;
(2) 创建头视图,头视图中有banner图和条件筛选框,标记banner图的高;
(3)合理设置上下滚动的容器视图的frame,它承载头视图和内容视图,不过需要禁止它的弹簧效果,实现悬浮框功能。
三、代码如下:
HeadView.h
// HeadView.h // SuspensionViewDemo // // Created by 夏远全 on 16/11/25. // Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved. // #import <UIKit/UIKit.h> @interface HeadView : UIView /** * 类方法创建头视图 */ +(instancetype)createHeadView:(CGRect)frame; @property (strong,nonatomic)UIView *animationView; //下划线动画视图 @end
HeadView.m
// HeadView.m // SuspensionViewDemo // // Created by 夏远全 on 16/11/25. // Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved. // #import "HeadView.h" #import "ViewController.h" #define padding 10 #define Width [[UIScreen mainScreen] bounds].size.width #define Height [[UIScreen mainScreen] bounds].size.height @interface HeadView () @property (strong,nonatomic)UIImageView *bannerView; //banner图 @property (strong,nonatomic)NSMutableArray *buttonNames; //标题按钮数组 @end @implementation HeadView /** * 懒加载 */ -(NSMutableArray *)buttonNames{ if (!_buttonNames) { _buttonNames = [NSMutableArray arrayWithObjects:@"运动",@"电玩",@"养生",@"娱乐",nil]; } return _buttonNames; } -(UIImageView *)bannerView{ if (!_bannerView) { _bannerView = [[UIImageView alloc]initWithFrame:CGRectMake(0,0,Width,160)]; _bannerView.image = [UIImage imageNamed:@"demo"]; } return _bannerView; } -(UIView *)animationView{ if (!_animationView) { _animationView = [[UIView alloc]initWithFrame:CGRectMake(0, CGRectGetMaxY(self.bannerView.frame)+40+padding/2, Width/4, padding/2)]; _animationView.backgroundColor = [UIColor redColor]; } return _animationView; } //重写初始化方法 -(instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { //1.创建轮播图 [self addSubview:self.bannerView]; //2.创建标题 for (int i=0; i<4; i++) { //按钮 UIButton *btn = [[UIButton alloc]init]; [btn setTitle:self.buttonNames[i] forState:UIControlStateNormal]; [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [btn addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside]; btn.tag = i; btn.backgroundColor = [UIColor whiteColor]; btn.titleLabel.font = [UIFont systemFontOfSize:14]; //分割线 UILabel *line = [[UILabel alloc]init]; line.tag = i; line.backgroundColor = [UIColor lightGrayColor]; //添加 [self addSubview:line]; [self addSubview:btn]; } //3.创建动画视图 [self addSubview:self.animationView]; } return self; } //类方法 +(instancetype)createHeadView:(CGRect)frame{ HeadView *headView = [[self alloc]initWithFrame:frame]; return headView; } #pragma mark - 按钮被点击 //点击按钮 -(void)buttonClick:(UIButton *)btn{ [UIView animateWithDuration:0.2 animations:^{ //移动动画视图的frame CGRect frame = self.animationView.frame; frame = CGRectMake(Width/4*btn.tag,frame.origin.y,frame.size.width,frame.size.height); self.animationView.frame = frame; //移动scrollView的偏移位置 ViewController *currentVC = (ViewController*)[self viewController]; [currentVC.contentView setContentOffset:CGPointMake(Width*btn.tag, 0) animated:NO]; }]; } //获取当前视图所在的控制器 - (UIViewController*)viewController { for (UIView* next = [self superview]; next; next = next.superview) { UIResponder* nextResponder = [next nextResponder]; if ([nextResponder isKindOfClass:[UIViewController class]]) { return (UIViewController*)nextResponder; } } return nil; } //设置frame -(void)layoutSubviews{ [super layoutSubviews]; for (UIView *mysubView in self.subviews) { if ([mysubView isKindOfClass:[UIButton class]]) { //按钮 UIButton *button = (UIButton *)mysubView; CGFloat X = (Width/4) * button.tag; button.frame = CGRectMake(X, CGRectGetMaxY(self.bannerView.frame)+padding/2, (Width/4), 40); } if ([mysubView isKindOfClass:[UILabel class]]) { //分割线 UILabel *line = (UILabel *)mysubView; CGFloat X = (Width/4) * line.tag - 0.5; line.frame = CGRectMake(X, CGRectGetMaxY(self.bannerView.frame)+1.5*padding,1,20); } } } @end
ContentView.h
// ContentView.h // SuspensionViewDemo // // Created by 夏远全 on 16/11/25. // Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved. // #import <UIKit/UIKit.h> @interface ContentView : UIScrollView //类方法创建 +(instancetype)shareWithFrame:(CGRect)frame; @end
ContentView.m
// ContentView.m // SuspensionViewDemo // // Created by 夏远全 on 16/11/25. // Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved. // #import "ContentView.h" #define XYQColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] #define XYQRandomColor XYQColor(arc4random_uniform(256), arc4random_uniform(256), arc4random_uniform(256)) #define SCREEN_W [[UIScreen mainScreen] bounds].size.width #define SCREEN_H [[UIScreen mainScreen] bounds].size.height @implementation ContentView //初始化 -(instancetype)initWithFrame:(CGRect)frame{ self = [super initWithFrame:frame]; if (self) { //放tableView for (int i=0; i<4; i++) { UIImageView *imgViw = [[UIImageView alloc]init]; imgViw.backgroundColor = XYQRandomColor; imgViw.frame = CGRectMake(SCREEN_W*i, 0, SCREEN_W, SCREEN_H-110); [self addSubview:imgViw]; } } return self; } //类方法创建 +(instancetype)shareWithFrame:(CGRect)frame{ ContentView *contentView = [[self alloc]initWithFrame:frame]; contentView.contentSize = CGSizeMake(SCREEN_W*4,frame.size.height); contentView.pagingEnabled = YES; contentView.bounces = NO; return contentView; } @end
ViewController.h
// ViewController.h // SuspensionViewDemo // // Created by 夏远全 on 16/11/25. // Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved. // #import <UIKit/UIKit.h> #import "ContentView.h" @interface ViewController : UIViewController /** * 内容视图 */ @property (strong,nonatomic)ContentView *contentView; @end
ViewController.m
// ViewController.m // SuspensionViewDemo // // Created by 夏远全 on 16/11/25. // Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved. // #import "ViewController.h" #import "HeadView.h" #define SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width #define SCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height @interface ViewController ()<UIScrollViewDelegate>{ UIScrollView *_containView; //大容器视图(存放头视图和内容视图) } /** * 头视图 */ @property (strong,nonatomic)HeadView *headView; @end @implementation ViewController /** * 给定头视图的高 */ static NSInteger const headHeight = 210; - (void)viewDidLoad { [super viewDidLoad]; [self.view setBackgroundColor:[UIColor whiteColor]]; //创建控件 [self setupControl]; } //创建控件 -(void)setupControl{ //1.设置容器视图 _containView = [[UIScrollView alloc] initWithFrame:self.view.bounds]; _containView.tag = -1; _containView.delegate = self; _containView.bounces = NO; //禁止它的弹簧效果 _containView.contentSize = CGSizeMake(SCREEN_WIDTH, SCREEN_HEIGHT+160); [self.view addSubview:_containView]; //2.创建头视图 _headView = [HeadView createHeadView:CGRectMake(0,0,SCREEN_WIDTH,headHeight)]; [_containView addSubview:_headView]; //3.创建内容视图 _contentView = [ContentView shareWithFrame:CGRectMake(0, headHeight, SCREEN_WIDTH, SCREEN_HEIGHT-110)]; _contentView.tag = -2; _contentView.delegate = self; [_containView addSubview:_contentView]; } #pragma mark - <UIScrollViewDeleagte> //设置下划动画视图的frame -(void)scrollViewDidScroll:(UIScrollView *)scrollView{ if (scrollView.tag == -2) { //横向的滚动内容视图 NSInteger page = scrollView.contentOffset.x/SCREEN_WIDTH; [UIView animateWithDuration:0.2 animations:^{ CGRect frame = self.headView.animationView.frame; frame = CGRectMake(SCREEN_WIDTH/4*page,frame.origin.y,frame.size.width,frame.size.height); self.headView.animationView.frame = frame; }]; } } @end
四、演示截图:(上拉到顶就悬浮了不能在上拉,下拉可以继续),点击按钮来回切换tableView