前言:
这个效果在UITableview里面可以见到,但是我这次做的页面如果使用UITableView,就显得太累赘了,而且这次的这个页面还有其他东西,用的悬浮效果也就这么一个,所以,多番考虑,决定自己写一个这样的效果,真的头都想破了。如果是使用 Frame 来写这个东西,那倒是非常简单,监听滚动视图的事件,然后在超出距离的时候设置frame。
但是,我这个UIScrollView里的子控件用的都是约束,突然混入Frame就很不合适的样子。所以,研究了下使用约束来写这个效果。
效果图:
代码如下:
代码地址:https://github.com/gityuency/ObjectiveCTools
示例代码类名 【FloatScrollViewController】
上代码!
注意:代码中使用到了 Masonry 框架来进行自动布局,请在使用时,添加到项目中。
.h
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface FloatScrollViewController : UIViewController
@end
NS_ASSUME_NONNULL_END
.m
#import "FloatScrollViewController.h"
#import "Masonry.h"
@interface FloatScrollViewController () <UIScrollViewDelegate>
///假的导航栏
@property (nonatomic, strong) UILabel *fakeNaviBar;
///滚动视图
@property (nonatomic, strong) UIScrollView *scrollView;
@end
@implementation FloatScrollViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
//把系统的导航栏隐藏
self.navigationController.navigationBar.hidden = YES;
//用自己的做的导航栏冒充,方便调试
self.fakeNaviBar = [[UILabel alloc] init];
self.fakeNaviBar.textColor = [UIColor whiteColor];
self.fakeNaviBar.backgroundColor = [UIColor redColor];
self.fakeNaviBar.text = @"这个是假的导航栏";
self.fakeNaviBar.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:self.fakeNaviBar];
[self.fakeNaviBar mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view);
make.top.equalTo(self.view).offset(120);
make.height.equalTo(@40);
}];
//滚动视图
self.scrollView = [[UIScrollView alloc] init];
self.scrollView.delegate = self;
if (@available(iOS 11.0, *)) {
self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
} else {
//
}
//self.scrollView.backgroundColor = [[UIColor brownColor] colorWithAlphaComponent:0.5];
[self.view addSubview:self.scrollView];
[self.view sendSubviewToBack:self.scrollView];
[self.scrollView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.equalTo(self.view);
make.top.equalTo(self.fakeNaviBar.mas_bottom); //滚动视图的顶部贴着假的导航栏的底部
make.bottom.equalTo(self.view).offset(-40);
}];
//这个作为基准线
UIView *viewContent_A = [[UIView alloc] init];
viewContent_A.backgroundColor = [UIColor magentaColor];
[self.scrollView addSubview:viewContent_A];
[viewContent_A mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.scrollView);
make.left.right.equalTo(self.scrollView);
make.centerX.equalTo(self.scrollView);
make.height.equalTo(@(400));
}];
//悬浮视图A
CGFloat Float_A_Height = 40;
UILabel *labelFloat_A = [[UILabel alloc] init];
labelFloat_A.backgroundColor = UIColor.greenColor;
labelFloat_A.text = @"我是悬浮视图 A";
[self.scrollView addSubview:labelFloat_A];
[labelFloat_A mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.greaterThanOrEqualTo(viewContent_A.mas_bottom); //距离上一个视图的底部 可以拉到很大很大
make.top.greaterThanOrEqualTo(self.fakeNaviBar.mas_bottom); //距离假导航栏的底部 可以拉到很大很大
make.left.right.equalTo(self.scrollView);
make.height.equalTo(@(Float_A_Height));
}];
//内容B
UIView *viewContent_B = [[UIView alloc] init];
viewContent_B.backgroundColor = UIColor.orangeColor;
[self.scrollView addSubview:viewContent_B];
[viewContent_B mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(viewContent_A.mas_bottom).offset(Float_A_Height); //这里的偏移量,就是上一个悬浮视图的高度
make.left.right.equalTo(self.scrollView);
make.height.equalTo(@(450));
}];
//悬浮视图B
UILabel *labelFloat_B = [[UILabel alloc] init];
labelFloat_B.backgroundColor = [UIColor greenColor];
labelFloat_B.text = @"我是悬浮视图 B";
[self.scrollView addSubview:labelFloat_B];
[labelFloat_B mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.greaterThanOrEqualTo(viewContent_B.mas_bottom).offset(0); //距离上一个视图的底部 可以拉到很大很大
make.top.greaterThanOrEqualTo(self.fakeNaviBar.mas_bottom); //距离假导航栏的底部 可以拉到很大很大
make.left.right.equalTo(self.scrollView);
make.height.equalTo(@40);
}];
//内容C
UIView *viewContent_C = [[UIView alloc] init];
viewContent_C.backgroundColor = UIColor.brownColor;
[self.scrollView addSubview:viewContent_C];
[viewContent_C mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(viewContent_B.mas_bottom).offset(40); //这里的偏移量,就是上一个悬浮视图的高度
make.left.right.equalTo(self.scrollView);
make.height.equalTo(@(450));
}];
//悬浮视图C
UILabel *labelFloat_C = [[UILabel alloc] init];
labelFloat_C.backgroundColor = [UIColor greenColor];
labelFloat_C.text = @"我是悬浮视图 C";
[self.scrollView addSubview:labelFloat_C];
[labelFloat_C mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.greaterThanOrEqualTo(viewContent_C.mas_bottom).offset(0); //距离上一个视图的底部 可以拉到很大很大
make.top.greaterThanOrEqualTo(self.fakeNaviBar.mas_bottom); //距离假导航栏的底部 可以拉到很大很大
make.left.right.equalTo(self.scrollView);
make.height.equalTo(@40);
}];
//最后一个填充视图
UIView *viewBottom = [[UIView alloc] init];
viewBottom.backgroundColor = UIColor.cyanColor;
[self.scrollView addSubview:viewBottom];
[viewBottom mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(viewContent_C.mas_bottom).offset(0);
make.left.right.equalTo(self.scrollView);
make.bottom.equalTo(self.scrollView);
make.height.equalTo(@800);
}];
//在最后,需要把漂浮的视图,都弄出来
[self.scrollView bringSubviewToFront:labelFloat_A];
[self.scrollView bringSubviewToFront:labelFloat_B];
[self.scrollView bringSubviewToFront:labelFloat_C];
}
@end
结语
这次的代码还是一样的烦。