文章目录
FooterView.h
定义枚举类型
typedef enum{
FooterViewStatusDragging,//拖拽上拉加载更多
FooterViewStatusReadyLoading,//松手加载更多
FooterViewStatusEndDragging//加载中
}FooterViewStatus;
和枚举属性变量
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface FooterView : UIView
typedef enum{
FooterViewStatusDragging,
FooterViewStatusReadyLoading,
FooterViewStatusEndDragging
}FooterViewStatus;
@property(nonatomic,assign)FooterViewStatus status;
+(instancetype)footerView;
@end
NS_ASSUME_NONNULL_END
FooterView.m
当视图即将加入父视图时调用:
通过父视图来设置子视图的尺寸。
-(void)willMoveToSuperview:(UIView *)newSuperview{
UITableView *tableView=(UITableView *)newSuperview;
//视频代码
//[self setFrame:CGRectMake(0, tableView.contentSize.height, CGRectGetWidth(tableView.bounds), 40)];
//自己调的
[self setFrame:CGRectMake(0, 2*tableView.contentSize.height+140, CGRectGetWidth(tableView.bounds), 40)];
[self.statusLabel setFrame:self.bounds];
}
对属性变量的调用,如果没有set和get方法,用_变量名的方式。比如枚举类型就没有set和get方法。
//不能用self.status
_status=status;
// FooterView.m
#import "FooterView.h"
@interface FooterView()
@property (nonatomic,strong)UILabel *statusLabel;
@end
@implementation FooterView
+(instancetype)footerView{
FooterView *footerView=[[self alloc]init];
[footerView setBackgroundColor:[UIColor blackColor]];
[footerView setStatusLabel:[[UILabel alloc]init]];
[footerView.statusLabel setText:@"上拉加载更多..."];
[footerView.statusLabel setTextColor:[UIColor whiteColor]];
[footerView.statusLabel setTextAlignment:NSTextAlignmentCenter];
[footerView addSubview:footerView.statusLabel];
return footerView;
}
-(void)willMoveToSuperview:(UIView *)newSuperview{
UITableView *tableView=(UITableView *)newSuperview;
//视频代码
//[self setFrame:CGRectMake(0, tableView.contentSize.height, CGRectGetWidth(tableView.bounds), 40)];
//自己调的
[self setFrame:CGRectMake(0, 2*tableView.contentSize.height+140, CGRectGetWidth(tableView.bounds), 40)];
[self.statusLabel setFrame:self.bounds];
}
- (void)setStatus:(FooterViewStatus)status{
//不能用self.status
_status=status;
switch (status) {
case FooterViewStatusDragging:
[self.statusLabel setText:@"上拉加载更多..."];
break;
case FooterViewStatusReadyLoading:
[self.statusLabel setText:@"松手加载更多..."];
break;
case FooterViewStatusEndDragging:
[self.statusLabel setText:@"加载中..."];
break;
default:
break;
}
}
@end
MainViewController.m
footerView添加的时候要添加到tableView上而不能添加到self即MainViewController上,
#import "MainViewController.h"
#import "FooterView.h"
@interface MainViewController ()<UITableViewDataSource,UITableViewDelegate>
@property (nonatomic,strong)FooterView *footerView;
@property (nonatomic,strong)UITableView *tableView;
@end
@implementation MainViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self setTitle:@"上拉加载更多"];
[self.view setBackgroundColor:[UIColor whiteColor]];
//[self setAutomaticallyAdjustsScrollViewInsets:NO];
[self setTableView:[[UITableView alloc] initWithFrame:CGRectMake(0, 64, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds)-64) style:UITableViewStylePlain]];
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
[self.view addSubview:self.tableView];
// Do any additional setup after loading the view.
}
-(FooterView*)footerView{
if (!_footerView) {
_footerView=[FooterView footerView];
[self.tableView addSubview:_footerView];
}
return _footerView;
}
#pragma mark - scroll view delegate -
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
//没有d拖拽居然也会调这个函数
//Y轴最大偏移量
CGFloat maxOffsetY=self.tableView.contentSize.height-self.tableView.frame.size.height;
CGFloat footerViewHeight=CGRectGetHeight(self.footerView.frame);
NSLog(@"%f,%f",maxOffsetY,footerViewHeight);
//开始拖拽
if(self.tableView.contentOffset.y>maxOffsetY
&&self.tableView.contentOffset.y<footerViewHeight+maxOffsetY){
[self.footerView setStatus:FooterViewStatusDragging];
}
//准备加载
else if(self.tableView.contentOffset.y>=footerViewHeight+maxOffsetY &&self.footerView.status!=FooterViewStatusEndDragging){
[self.footerView setStatus:FooterViewStatusReadyLoading];
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
//松手加载更多
if(self.footerView.status==FooterViewStatusReadyLoading){
[self.footerView setStatus:FooterViewStatusEndDragging];
[UIView animateWithDuration:0.2 animations:^{
[self.tableView setContentInset:UIEdgeInsetsMake(0, 0, CGRectGetHeight(self.footerView.bounds), 0)];
}];
}
//恢复原状态
else{
[UIView animateWithDuration:0.2 animations:^{
[self.tableView setContentInset:UIEdgeInsetsZero];
}];
}
}
#pragma mark - table view dalegate -
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
return 100;
}
#pragma mark - table view data source -
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
return 8;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell=[[UITableViewCell alloc]init];
cell.textLabel.text=[NSString stringWithFormat:@"第%zd行",indexPath.row];
return cell;
}
@end
ios view的frame和bounds之区别
参考:https://www.jianshu.com/p/320cacb9e4f0
https://blog.csdn.net/mad1989/article/details/8711697
-(CGRect)frame{
return CGRectMake(self.frame.origin.x,self.frame.origin.y,self.frame.size.width,self.frame.size.height);
}
-(CGRect)bounds{
return CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
}
很明显,bounds的原点是(0,0)点(就是view本身的坐标系统,默认永远都是0,0点,除非认为setbounds),而frame的原点却是任意的(相对于父视图中的坐标位置)。
原文:https://blog.csdn.net/mad1989/article/details/8711697
frame: 该view在父view坐标系统中的位置和大小。(参照点是,父亲的坐标系统)
bounds:该view在本地坐标系统中的位置和大小。(参照点是,本地坐标系统,就相当于ViewB自己的坐标系统,以0,0点为起点)
设置bounds可以影响到子view的位置和大小:
UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(20, 20, 280, 250)];
[view1 setBounds:CGRectMake(-20, -20, 280, 250)];
view1.backgroundColor = [UIColor redColor];
[self.view addSubview:view1];//添加到self.view
NSLog(@"view1 frame:%@========view1 bounds:%@",NSStringFromCGRect(view1.frame),NSStringFromCGRect(view1.bounds));
UIView *view2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
view2.backgroundColor = [UIColor yellowColor];
[view1 addSubview:view2];//添加到view1上,[此时view1坐标系左上角起点为(-20,-20)]
NSLog(@"view2 frame:%@========view2 bounds:%@",NSStringFromCGRect(view2.frame),NSStringFromCGRect(view2.bounds));
contentSize:
contentSize是scrollview可以滚动的区域,比如frame = (0 ,0 ,320 ,480) contentSize = (320 ,960),代表你的scrollview可以上下滚动,滚动区域为frame大小的两倍。
contentInset:
contentInset的单位是UIEdgeInsets,默认值为UIEdgeInsetsZero,也就是没有扩展的边。
UIEdgeInsets 设置包围tableView的坐标:
typedef struct UIEdgeInsets {
CGFloat top, left, bottom, right;
} UIEdgeInsets;
代表 上、 左、 下、 右 四个方向扩展出去的值。
contentOffset:
contentOffset是UIScrollView当前显示区域的顶点相对于frame顶点的偏移量,例如上面的例子如果拉到最下面,则contentOffset就是(0, 480),也就是y偏移了480。