iOSiOS学习专题ios

UITableView和UIScrollView分析

2016-07-31  本文已影响3054人  CoderZb

解决添加到ScrollView上的UITableView控件自动向下偏移64像素的问题


ScrollView的frame和的contentSize的区别


情况不同决定了UITableView是否需要设置宽高

   UIView *childVcView = self.childViewControllers[i].view;
   childVcView.zb_X = i * scrollView.zb_width;
   [scrollView addSubview:childVcView];
        
UITableView *tableView = [[UITableView alloc] init];
 tableView.zb_height = scrollView.zb_height;
 tableView.zb_width = scrollView.zb_width;

思想:一个TableView对应一个控制器(本质是类)。一个TableView有自己专门的数据源。

5个TableView对应一个类(用于衬托1个TableView对应1个类)

#import "ViewController.h"
#import "UIView+Frame.h"

#define ZBColor(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define ZBRandomColor ZBColor(arc4random_uniform(255), arc4random_uniform(255), arc4random_uniform(255))


@interface ViewController ()<UITableViewDataSource>
//@property (nonatomic,weak)UIScrollView *scrollView;
@property(nonatomic,strong)UITableViewCell *cell;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //将scrollView添加到控制器的view上
    UIScrollView *scrollView = [[UIScrollView alloc] init];
    scrollView.frame = self.view.bounds;
    scrollView.backgroundColor = [UIColor redColor];
    [self.view addSubview:scrollView];
    //将5个TableView添加到scrollView上。scrollView的contentSize为5个TableView的宽度
    for (NSInteger i =0; i < 5 ; i++) {
        UITableView *tableView = [[UITableView alloc] init];
        tableView.backgroundColor = ZBRandomColor;

        tableView.zb_height = scrollView.zb_height;
        tableView.zb_width = scrollView.zb_width;
        tableView.zb_X = i *tableView.zb_width;
        //5个tableView的数据源都是1个控制器,所以5个TableView上都显示一样的数据
        tableView.dataSource =self;
        tableView.tag=i;
        [scrollView addSubview: tableView];
    }
    scrollView.contentSize = CGSizeMake(5 *self.view.bounds.size.width, 0);
    scrollView.pagingEnabled =YES;
    
}


-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    if (tableView.tag == 0) return 5;
    if (tableView.tag == 1) return 10;
    if (tableView.tag == 2) return 15;
    if (tableView.tag == 3) return 20;
    else
        return 25;
    
}
static NSString * const ID = @"ce";
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
if(tableView.tag == 0){
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell  alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor clearColor];
    }
        cell.textLabel.text = [NSString stringWithFormat:@"第%ld个tableView-第%zd个cell",tableView.tag,indexPath.row];
         return cell;
}else if(tableView.tag == 1){
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell  alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor clearColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"第%ld个tableView-第%zd个cell",tableView.tag,indexPath.row];
    return cell;

}else if(tableView.tag == 2){
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

    if (cell == nil) {
        cell = [[UITableViewCell  alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor clearColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"第%ld个tableView-第%zd个cell",tableView.tag,indexPath.row];
    return cell;
}else if(tableView.tag == 3){
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    if (cell == nil) {
        cell = [[UITableViewCell  alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor clearColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"第%ld个tableView-第%zd个cell",tableView.tag,indexPath.row];
    return cell;
}else{

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    if (cell == nil) {
        cell = [[UITableViewCell  alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor clearColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"第%ld个tableView-第%zd个cell",tableView.tag,indexPath.row];
    return cell;


}
}
@end

41-04.gif

1个TableView对应1个类

ViewController.h文件

#import "ViewController.h"
#import "UIView+Frame.h"
#import "ZBAllViewController.h"
#import "ZBPictureViewController.h"
#import "ZBVideoViewController.h"
#import "ZBVoiceViewController.h"
#import "ZBWordViewController.h"

#define ZBColor(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define ZBRandomColor ZBColor(arc4random_uniform(255), arc4random_uniform(255), arc4random_uniform(255))


@interface ViewController ()<UITableViewDataSource>
//@property (nonatomic,weak)UIScrollView *scrollView;
@property(nonatomic,strong)UITableViewCell *cell;
@end

@implementation ViewController

- (void)viewDidLoad {
   [super viewDidLoad];
   // 初始化子控制器
   [self setupChildVcs];
   
   // scrollView
   [self setupScrollView];
   
}

/**
*  初始化子控制器
*/
- (void)setupChildVcs
{
   [self addChildViewController:[[ZBAllViewController alloc] init]];
   [self addChildViewController:[[ZBVideoViewController alloc] init]];
   [self addChildViewController:[[ZBVoiceViewController alloc] init]];
   [self addChildViewController:[[ZBPictureViewController alloc] init]];
   [self addChildViewController:[[ZBWordViewController alloc] init]];
}

/**
*  scrollView
*/
- (void)setupScrollView
{
   UIScrollView *scrollView = [[UIScrollView alloc] init];
   scrollView.frame = self.view.bounds;
   [self.view addSubview:scrollView];
   
   // 添加5个模块
   for (NSInteger i = 0; i < 5; i++) {
       /*
        3个方法的总结:前提:控件添加到UIScrollView上。
                    方法1没有设置y坐标,所以UITableView显示时会向下偏移20像素
                    方法2和方法3设置了y坐标,并且设置为0,使UITableView显示时y距屏幕顶部为0,所以UITableView显示时会向下偏移20像素
       
        */
       //方法1:仅仅是设置childVcView的x坐标,childVcView的y坐标没有设置。这样会导致程序运行时,childVcView也就是UITableView不是填充整个屏幕,而是向下偏移20像素的距离(状态栏的原因)
       UIView *childVcView = self.childViewControllers[i].view;
       childVcView.zb_X = i * scrollView.zb_width;
       [scrollView addSubview:childVcView];
       
       
       /*  方法2:
       //注意:childVcView指针存着的是控制器的view,而不是控制器,因为等号右侧有.view,所以childVcView这时候代表的是一个view。.所以后面两行代码childVcView都不用加上.view。
       UIView *childVcView = self.childViewControllers[i].view;//取控制器的view
        
        childVcView.frame = CGRectMake(i * scrollView.zb_width, 0, scrollView.zb_width, scrollView.zb_height);//设置视图的frame。
       [scrollView addSubview:childVcView];
       */
       /* 方法3:
       //childViewControllers中的子控制器真实是UITableViewController,因为UITableViewController继承UIViewController,所以childVcView的类型也可以写成UIViewController
       //childVcView指针存着的是控制器,因为没有等号右侧没有.view。所以childVcView这时候代表的是一个控制器,后两行代码childVcView后面必须加上.view。因为我们最终是要把view添加到scrollView上的。
       UIViewController *childVcView = self.childViewControllers[i];//取控制器
       childVcView.view.frame = CGRectMake(i * scrollView.zb_width, 20, scrollView.zb_width, scrollView.zb_height);//设置控制器的view的frame
       [scrollView addSubview:childVcView.view];//将控制器的view添加到scrollView上面
        */
   }
   
   // 其他设置
   scrollView.contentSize = CGSizeMake(5 * scrollView.zb_width, 0);
   scrollView.pagingEnabled = YES;
}

@end

ZBPictureViewController文件,

import "ZBPictureViewController.h"
#define ZBColor(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define ZBRandomColor ZBColor(arc4random_uniform(255), arc4random_uniform(255), arc4random_uniform(255))
#import "ZBConst.h"
@interface ZBPictureViewController ()

@end

@implementation ZBPictureViewController

- (void)viewDidLoad {
   [super viewDidLoad];
   
   self.tableView.backgroundColor = ZBRandomColor;
}
#pragma mark - UITableViewDataSource

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
   
   return 30;
   
}
static NSString *ID = @"ce";
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
   
   UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:ID];
   if (cell == nil) {
       cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
       cell.backgroundColor = [UIColor clearColor];
   }
   
   cell.textLabel.text = [NSString stringWithFormat:@"%@ - %zd",self.class,indexPath.row];
   return cell;
}


@end

41-03.gif

addChildViewController和addSubview区分

精华例子1:
//控制器才能添加到控制器中。因为self代表了控制器,如果某个对象要添加到控制器中,那么这个对象必须是控制器。【苹果公司规定】
 ZBAllViewController *vc1 = [[ZBAllViewController alloc] init];
    [self addChildViewController:vc1];
    
//View才能添加到View中。因为self.scrollView本身就是个View,它不是控制器,所以如果某个对象要添加到self.scrollView这个view中时,这个而对象必须是View,因为childVC是控制器的对象,所以必须把childVC再进行细化,拿到childVc的view。即使childVc.view
 UIViewController *childVc = self.childViewControllers[index];
 [self.scrollView addSubview:childVc.view];
精华例子2:
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    //以下演示的给对象添加backgroundColor,frame等等属性,这些属性一定要在view上进行。
    
    UIView *zb  = [[UIView alloc]init];
    //zb是个view,已经精确到了view,所以直接可以访问backgroundColor,frame属性
    zb.backgroundColor = [UIColor redColor];
    zb.frame =CGRectMake(80, 80, 100,100);
    //self是控制器,必须精确到控制器的view,才能将zb添加到控制器的view上,否则报错。
    [self.view addSubview:zb];
    
    //虽说下面的显示不出运行结果,但是我们的目的达到了
    
    UIViewController *vc = [[UIViewController alloc] init];
    //vc是个控制器,必须精确到vc.view,才能访问backgroundColor,frame属性
    vc.view.backgroundColor = [UIColor yellowColor];
    vc.view.frame =CGRectMake(300, 80, 100, 100) ;
    //vc是个控制器,所以可以添加到self上。这个时候再用self.view就会报错
    [self addChildViewController:vc];
}




@end


UIViewController和UITableViewController创建出来时,y的坐标分别为多少

40-26.png

创建TableView的3中方法

方法1代码+截图
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end


#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, weak) UITableView *tableView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(80, 100, 200, 300);
    tableView.backgroundColor = [UIColor grayColor];
    //数据源
    tableView.dataSource = self;
    //代理
    tableView.delegate = self;
    
    [self.view addSubview:tableView];
    

}
#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"contentSize.height = %f", tableView.contentSize.height);
}

#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end


41-05.gif
方法2代码+截图
#import <UIKit/UIKit.h>

@interface ViewController : UITableViewController


@end


#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

}


#pragma mark -代理方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"contentSize.height = %f", tableView.contentSize.height);
}

#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}
#pragma mark - 数据源方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor yellowColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end

41-02.png
方法3代码+截图
#import <UIKit/UIKit.h>

@interface ViewController : UITableViewController


@end

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

}


#pragma mark -代理方法
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"contentSize.height = %f", tableView.contentSize.height);
}

#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 20;
}
#pragma mark - 数据源方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end



UIScrollView的滚动

UIScrollView和UITableView的偏移量正负详解


UIScrollView和UITableView滚动的是内容而不是控件


  1.把图片添加到UIScrollView上.本质上是把图片添加到了UIScrollView的内容上。
  我们滚动屏幕时,滚动的不是UIScrollView这个控件(窗口),滚动的是内容.
  我们手动滚动内容时(也可以利用代码控制contentOffset的偏移量实现滚动内容),图片会经过这个UIScrollView(窗口),经过窗口的内容会被我们看到。
  如果你认为图片添加到了UIScrollView这个控件上,假设图片添加到了UIScrollView控件的外侧(屏幕的外侧),这样我们无论怎么滚动,也永远看不到这张图片。因为UIScrollView此时就是一个供我们看东西的窗口,超过窗口的东西我们永远看不到,你把图片添加到了这个窗口的外侧,而不是添加到了内容上,你滚动内容时,内容里面并没有图片,内容经过窗口时,怎么会显示这张图片(UIScrollView就是窗口,通过这个窗口我们才能看到图片,超过这个窗口的图片,我们永远看不到。类比井底之蛙)

  2.为什么能滚动?
  contentSize不能滚动,contentSize仅仅是提供了一个供我们滚动的矩形范围。scrollView的内容能滚动(前提:我们必须用手滚内容啊,只要触摸到了内容,就能滚,底层帮我们做好了,不要问为什么)。
  
  3. UIScrollView的内容是啥,包括啥? 内容是虚拟的,我们看不到,但是实际存在,如果你把2张图片通过[self.scrollView addSubview:imageV];的形式添加到了内容中,那么内容就是两张图片。即,执行addSubview:的操作,执行addSubview:方法的参数就是内容,

  4.如果你现在仍理解为把图片添加到UIScrollView上,你就无法理解滚动的谁?为什么能滚动?窗口是谁?contentSize的深层次含义?
  
  5.看UITableView动态截图+ppt截图你就理解UIScrollView了:UITableView控件并不能滚动,而是内容能滚动。

UITableView的滚动

//本质:所能滚动的内容尺寸就是一个宽为100,高位200的矩形
    tableView.contentSize = CGSizeMake(100, 200);
    
//类比UIScrollView设置滚动的内容尺寸
    scrollView.contentSize = CGSizeMake(100, 200);


UITableView的属性:frame,ContentOffset,ContentInset,ContentSize区分


没有cell,没有contentInset,没有TableHeadView、TableHeaderView的情况

#import "ViewController.h"

@interface ViewController () <UITableViewDelegate>
@property (nonatomic, weak) UITableView *tableView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(100, 100, 200, 300);
    tableView.backgroundColor = [UIColor grayColor];
    tableView.delegate = self;
    tableView.rowHeight = 40;
    [self.view addSubview:tableView];
    self.tableView = tableView;
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"contentSize.height = %f", self.tableView.contentSize.height);
}
#pragma mark - UITableViewDelegate
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{

    return 0;

}
@end

41-06.gif 41-16.png

有cell,没有contentInset,没有TableHeadView、TableHeaderView的情况

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(100, 100, 200, 300);
    tableView.backgroundColor = [UIColor grayColor];
    tableView.dataSource = self;
    tableView.delegate = self;
    tableView.rowHeight = 40;
    
    [self.view addSubview:tableView];
    
    
}


#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"\t内容尺寸的偏移量y:contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"\t内容尺寸的高度:contentSize.height = %f", tableView.contentSize.height);
}

#pragma mark - 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end

41-07.gif 41-17.png

有cell,有contentInset,没有TableHeadView、TableHeaderView的情况

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(100, 100, 200, 300);
    tableView.backgroundColor = [UIColor grayColor];
    tableView.dataSource = self;
    tableView.delegate = self;
    tableView.rowHeight = 40;
    [self.view addSubview:tableView];
    
    // 内边距
    //距tableView内容尺寸顶部的距离为64,距tableView内容尺寸底部的距离为49。即停止拖动时候顶部多出64的距离,底部多出49的距离,永久性的多出这些距离。
    tableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0);
    


}

#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"\t内容尺寸的偏移量y:contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"\t内容尺寸的高度:contentSize.height = %f", tableView.contentSize.height);
}

#pragma mark - 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end





41-08.gif 41-18.png
详情分析:

有cell,没有contentInset,有TableHeadView、TableHeaderView的情况

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(100, 100, 200, 300);
    tableView.backgroundColor = [UIColor grayColor];
    tableView.dataSource = self;
    tableView.delegate = self;
    tableView.rowHeight = 40;
    [self.view addSubview:tableView];
    
    // header - footer
    UIView *header = [[UIView alloc] init];
    header.frame = CGRectMake(0, 0, tableView.frame.size.width, 64);
    header.backgroundColor = [UIColor yellowColor];
    tableView.tableHeaderView = header;
    
    UIView *footer = [[UIView alloc] init];
    footer.frame = CGRectMake(0, 0, tableView.frame.size.width, 49);
    footer.backgroundColor = [UIColor greenColor];
    tableView.tableFooterView = footer;

}



#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"\t内容尺寸的偏移量y:contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"\t内容尺寸的高度:contentSize.height = %f", tableView.contentSize.height);
}

#pragma mark - 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end


41-09.gif 41-19.png
详情分析:

有cell,有contentInset,有TableHeadView、TableHeaderView的情况

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(100, 100, 200, 300);
    tableView.backgroundColor = [UIColor grayColor];
    tableView.dataSource = self;
    tableView.delegate = self;
    tableView.rowHeight = 40;
    [self.view addSubview:tableView];

    
    // 内边距
    //距tableView内容尺寸顶部的距离为64,距tableView内容尺寸底部的距离为49。即停止拖动时候顶部多出64的距离,底部多出49的距离。
    tableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0);
    
    // header - footer
    UIView *header = [[UIView alloc] init];
    header.frame = CGRectMake(0, 0, tableView.frame.size.width, 64);
    header.backgroundColor = [UIColor yellowColor];
    tableView.tableHeaderView = header;
    
    UIView *footer = [[UIView alloc] init];
    footer.frame = CGRectMake(0, 0, tableView.frame.size.width, 49);
    footer.backgroundColor = [UIColor greenColor];
    tableView.tableFooterView = footer;
    
}


#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"\t内容尺寸的偏移量y:contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"\t内容尺寸的高度:contentSize.height = %f", tableView.contentSize.height);
}

#pragma mark - 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end

41-10.gif 41-20.png
详情分析:

有cell,没有contentInset,没有TableHeadView、TableHeaderView,有额外添加的子控件{0, -40, 375, 40}

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(100, 100, 200, 300);
    tableView.backgroundColor = [UIColor grayColor];
    tableView.dataSource = self;
    tableView.delegate = self;
    tableView.rowHeight = 40;
    
    [self.view addSubview:tableView];
    
    
    // 额外添加的子控件 会显示在TableVIew的内部
    UIView *zb = [[UIView alloc] init];
    zb.frame = CGRectMake(0, -40, tableView.frame.size.width, 40);
    zb.backgroundColor = [UIColor blueColor];
    [tableView addSubview:zb];
}

#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"\t内容尺寸的偏移量y:contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"\t内容尺寸的高度:contentSize.height = %f", tableView.contentSize.height);
}

#pragma mark - 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end

41-11.gif 41-21.png
详情分析:

有cell,有contentInset,没有TableHeadView、TableHeaderView,有额外添加的子控件{0, -40, 375, 40}

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(100, 100, 200, 300);
    tableView.backgroundColor = [UIColor grayColor];
    tableView.dataSource = self;
    tableView.delegate = self;
    tableView.rowHeight = 40;
    [self.view addSubview:tableView];
    // 内边距
    //距tableView内容尺寸顶部的距离为64,距tableView内容尺寸底部的距离为49。即停止拖动时候顶部多出64的距离,底部多出49的距离。
    tableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0);
  
    // 额外添加的子控件 会显示在TableVIew的内部
    UIView *header = [[UIView alloc] init];
    header.frame = CGRectMake(0, -40, tableView.frame.size.width, 40);
    header.backgroundColor = [UIColor blueColor];
    [tableView addSubview:header];
}

#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"\t内容尺寸的偏移量y:contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"\t内容尺寸的高度:contentSize.height = %f", tableView.contentSize.height);
}

#pragma mark - 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end
41-22.png
详细分析:

有cell,没有contentInset,有TableHeadView、TableHeaderView,有额外添加的子控件{0, -40, 375, 40}


#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, weak) UITableView *tableView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(100, 100, 200, 300);
    tableView.backgroundColor = [UIColor grayColor];
    tableView.dataSource = self;
    tableView.delegate = self;
    tableView.rowHeight = 40;

    [self.view addSubview:tableView];
    self.tableView = tableView;

    // header - footer
    UIView *header = [[UIView alloc] init];
    header.frame = CGRectMake(0, 0, tableView.frame.size.width, 64);
    header.backgroundColor = [UIColor yellowColor];
    tableView.tableHeaderView = header;
    
    UIView *footer = [[UIView alloc] init];
    footer.frame = CGRectMake(0, 0, tableView.frame.size.width, 49);
    footer.backgroundColor = [UIColor greenColor];
    tableView.tableFooterView = footer;
    
    // 额外添加的子控件 会显示在TableVIew的内部
    UIView *zb = [[UIView alloc] init];
    zb.frame = CGRectMake(0, -40, tableView.frame.size.width, 40);
    zb.backgroundColor = [UIColor blueColor];
    [tableView addSubview:zb];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"\n \n 内容尺寸的高度:contentSize.height = %f", self.tableView.contentSize.height);
}

#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"\t内容尺寸的偏移量y:contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"\t内容尺寸的高度:contentSize.height = %f", tableView.contentSize.height);
}

#pragma mark - 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end


41-13.gif 41-23.png

有cell,有contentInset,有TableHeadView、TableHeaderView,有额外添加的子控件{0, -40, 375, 40}

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    UITableView *tableView = [[UITableView alloc] init];
    tableView.frame = CGRectMake(100, 100, 200, 300);
    tableView.backgroundColor = [UIColor grayColor];
    tableView.dataSource = self;
    tableView.delegate = self;
    tableView.rowHeight = 40;
    [self.view addSubview:tableView];

    
    // 内边距
        //距tableView内容尺寸顶部的距离为64,距tableView内容尺寸底部的距离为49。即停止拖动时候顶部多出64的距离,底部多出49的距离。
    tableView.contentInset = UIEdgeInsetsMake(64, 0, 49, 0);
    
    // header - footer
    UIView *header = [[UIView alloc] init];
    header.frame = CGRectMake(0, 0, tableView.frame.size.width, 64);
    header.backgroundColor = [UIColor yellowColor];
    tableView.tableHeaderView = header;
    
    UIView *footer = [[UIView alloc] init];
    footer.frame = CGRectMake(0, 0, tableView.frame.size.width, 49);
    footer.backgroundColor = [UIColor greenColor];
    tableView.tableFooterView = footer;

    // 额外添加的子控件 会显示在TableVIew的内部
    UIView *zb = [[UIView alloc] init];
    zb.frame = CGRectMake(0, -40, tableView.frame.size.width, 40);
    zb.backgroundColor = [UIColor blueColor];
    [tableView addSubview:zb];
}



#pragma mark - <UITableViewDelegate>
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSLog(@"\t内容尺寸的偏移量y:contentOffset.y = %f", tableView.contentOffset.y);
    NSLog(@"\t内容尺寸的高度:contentSize.height = %f", tableView.contentSize.height);}

#pragma mark - 数据源
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
   
    return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *ID = @"cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
        cell.backgroundColor = [UIColor redColor];
    }
    cell.textLabel.text = [NSString stringWithFormat:@"%@-%zd", self.class, indexPath.row];
    return cell;
}
@end
41-15.gif 41-24.png

没有cell,没有contentInset,有TableHeadView、TableHeaderView,没有有额外添加的子控件{0, -40, 375, 40}

#import "ViewController.h"

@interface ViewController ()
@property (nonatomic, weak) UITableView *tableView;
@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  
  UITableView *tableView = [[UITableView alloc] init];
  tableView.frame = CGRectMake(100, 100, 200, 300);
  tableView.backgroundColor = [UIColor grayColor];
  tableView.rowHeight = 40;

  [self.view addSubview:tableView];
  self.tableView = tableView;

  // header - footer
  UIView *header = [[UIView alloc] init];
  header.frame = CGRectMake(0, 0, tableView.frame.size.width, 64);
  header.backgroundColor = [UIColor yellowColor];
  tableView.tableHeaderView = header;
  
  UIView *footer = [[UIView alloc] init];
  footer.frame = CGRectMake(0, 0, tableView.frame.size.width, 49);
  footer.backgroundColor = [UIColor greenColor];
  tableView.tableFooterView = footer;

}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
  NSLog(@"\t内容尺寸的高度:contentSize.height = %f", self.tableView.contentSize.height);
}

@end

41-14.gif 41-25.png

详细分析:

点击控制器的touchbegan 打印113,就是64+49=113. 并且拖动内容尺寸,脱完松手,又会弹回来,因为内容尺寸小于UITableView的尺寸


精华截图动画

43-01.gif

全屏穿透效果知识点:

上一篇 下一篇

猜你喜欢

热点阅读