IOS 开发(三) —— 实现Table列表、瀑布流列表、页面滚动切换

一、使用UITableView 实现简单列表

UITableView

  • tableHeaderView
  • tableFooterView
  • UITableViewCell

1-1、UITableViewDataSource

UITableView 作为视图,只负责展示,协助管理,不管理数据 需要开发者为 UITableView 提供展示所需要的数据及 Cell 通过 delegate 的模式,需要实现 UITableViewDataSource

  • numberOfRowsInSection:(NSInteger)section;
  • cellForRowAtIndexPath:(NSIndexPath) indexPath;
objc 复制代码
- (void)viewDidLoad {
  [super viewDidLoad];
  self.view.backgroundColor = [UIColor whiteColor];
  UITableView *tableView= [[UITableView alloc] initWithFrame:self.view.bounds];
  tableView.dataSource = self;
  [self.view addSubview:tableView];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
  return 20;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"id"];
  cell.textLabel.text = @"主标题";
  cell.detailTextLabel.text = @"副标题";
  cell.imageView.image = [UIImage imageNamed:@"home"];
  return cell;
}

以上就实现了一个简单的列表

1-2、UITableViewCell 的重用

tableView 可是区域优化

objc 复制代码
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
  //  UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"id"];
  //  由系统提供的服用逻辑,先到系统回收池中去取
      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"id"];
      if(!cell){
          cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"id"];
      }
      // cell.textLabel.text = @"主标题";
      cell.textLabel.text = [NSString stringWithFormat:@"主标题 - %@",@(indexPath.row)];  //@"主标题";
      cell.detailTextLabel.text = @"副标题";
      cell.imageView.image = [UIImage imageNamed:@"home"];
      return cell;
  }

利用系统回收池优化列表cell的生成

113、NSIndexPath

objc 复制代码
 cell.textLabel.text = [NSString stringWithFormat:@"主标题 - %@",@(indexPath.row)];  

1-4、UITableViewDelegate 设置点击列表进入详情页

  • 提供滚动过程中,UITableViewCell的出现、消失时机
  • 提供UITableVIewCell 的高度、headers 以及 footers 设置
  • 提供 UITableViewCell 各种行为的回调 (点击、删除等)

从上面的 UITableViewDataSource 为我们提供了数据, UITableViewDelegate 提供了事件,消失的时机 header、footer 设置, 所以在

objc 复制代码
// UITableViewDataSource 提供数据
   tableView.dataSource = self;
//UITableViewDelegate 提供 事件 消失的时机 header、footer 设置
   tableView.delegate = self;

像dataSource一样设置delegate, 然后 UITableViewDelegate 设置到依赖中

objc 复制代码
  @interface** ViewController ()<UITableViewDataSource,UITableViewDelegate>

进入会发现系统提供的delegate 方法, 下面简单使用两个

objc 复制代码
// UITableView delegate
// 设置高度
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
  return 100;
}
// 点击哪个cell,获取index 实现一个点击进入对应页面的逻辑, 新建一个 uiviewcontroller
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
  UIViewController *controller = [[UIViewController alloc] init];
  controller.view.backgroundColor = [UIColor systemPinkColor];
  controller.title = [NSString stringWithFormat:@"%@", @(indexPath.row)];
  [self.navigationController pushViewController:controller animated:YES];
}

效果如下

1-5、总结 UITableView

UITableView 是系统为我们提供的一个最基础的展示列表类型的组件,同时为用户界面表视图提供了一些默认的基础样式,我们可以添加页眉页脚。 UITableViewCell为我们提供了销售的复用回收逻辑,我们就可以让一个非常长的列表去实现。屏幕中展示了很少的数量,在滚动的过程中进行一个复用回收 它也提供了一些基础的功能,比如点击删除以及插入等等 我们页实现了一个点击的逻辑,就是我们创建UItableview。同时呢,设置它的data source和data delegate,然后选择我们要需要实现的函数,进而实现我们自定义的一个操作

二、UICollectionView

2-1、UICollectionView

UITableView 的不足, 对于视频类, 小红书瀑布流类的,UITableVIew 就很不好实现, 苹果为我们提供了一个更好使用这个布局的 UICollectionView

UICollectionView 布局更灵活, 系统提供了更灵活的视图和动画

相同的设计理念 仍然是 datasource 和 delegate 驱动

  • 由于一行可以展示多个视图, row 不能准确表达一行, 所以系统提供了 item 仍然在 NSIndexPath

UICollectionViewDataSource 处理数据相关 每行

  • numberOfItemsInSection:(NSInter)section;
  • cellForItemAtIndexPath:(NSIndexPath) indexPath;

UICollectionViewDelegate 处理事件、点击等逻辑

  • willDisplayCell / endDisplayCell...
  • -(void)collectionView:(UICollectionView) collectionView didSelectItemAtIndexPath(NSIndexPath*) indexPath;

UICollectionViewCell 与 UITableViewCell 区别

  • 不提供默认样式

    • 不是以行为设计基础
    • 只有 contentView/backgroundView
    • 继承自 UICollectionReusableView
  • 必须先注册 Cell 类型 用于重用

    • -(void)registerClass:(Class)cellClass forCellWithReuseIdentifier:(NSstring)identifier;
    • -(_kindof UICollectionViewCell) dequeueReusableCellWithReuseIdentifier:(NSString) identifier...

2-2、创建UICollectionView 基本列表

在视频列表实现一个基本的 UICollectionView 的列表

创建一个controler 代表视频,里面包含 UICollectionView 的列表

GTVideoViewController.m

objc 复制代码
#import "GTVideoViewController.h"
@interface GTVideoViewController ()<UICollectionViewDataSource,UICollectionViewDelegate>
@end
@implementation GTVideoViewController

- (instancetype) init{
    self = [super init];
    if(self){
        self.tabBarItem.title = @"视频";
        self.tabBarItem.image = [UIImage imageNamed:@"expore"];
        self.tabBarItem.selectedImage = [UIImage imageNamed:@"expore-active"];
    }
    return self;
}
- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor whiteColor];
    // 创建一个layout
    UICollectionViewLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
    UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout: flowLayout];
    // 注册一个cell
    [collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"UICollectionViewCell"];
    // 添加datasource 和 delegate
    collectionView.delegate = self;
    collectionView.dataSource=self;
    
    [self.view addSubview:collectionView];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return 200;
}
- (__kindof UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    // 从系统回收池内获取 cell 去不到会从上面的注册 cell 的地方创建
    UICollectionView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"UICollectionViewCell" forIndexPath: indexPath];
        cell.backgroundColor  = [UIColor redColor];
        return cell;
}
@end

2-3、ICollectionViewLayout

ICollectionViewLayout 用于生成 UICollectionView 布局信息的类

objc 复制代码
 // 创建一个layout
  UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
  flowLayout.minimumLineSpacing = 10; // 设置行间距
  flowLayout.minimumInteritemSpacing = 10; // 设置每个item之间间距
  flowLayout.itemSize = CGSizeMake((self.view.frame.size.width-10)/2,300); // 设置每个item的宽度
objc 复制代码
// 通过 delegate
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath{
  if(indexPath.item %3 ==0){
      return CGSizeMake(self.view.frame.size.width,200);
  }else{
      return CGSizeMake((self.view.frame.size.width-10)/2,300);
  }
}

2-4、总结

UICollectionView 跟 UITableView 一样 提供了更灵活、可定制的列表类型视图组件、提供了默认基础的 Flow 样式布局、 提供了针对 UICollectionView 的复用回收逻辑、提供列表其他功能,如点击、删除、插入以及布局切换等

三、 UIScrollView 实现横向滑动

UIScrollView 是 UIView 的一个子类,负责滚动

objc 复制代码
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
scrollView.backgroundColor = [UIColor lightGrayColor];
scrollView.contentSize = CGSizeMake(self.view.bounds.size.width * 5, self.view.bounds.size.height);
scrollView.showsHorizontalScrollIndicator = YES;
[self.view addSubview:scrollView];

其他常用属性和方法

  • scrollEnabled 是否滚动
  • pagingEnabled 翻页效果
  • showHorizontalScrollIndicator 展示垂直滚动条
  • showVerticalScrollIndicator 展示水平滚动条
  • setContentOffset:animated:

实现带五个屏幕的分页效果

objc 复制代码
#import "GTRecommendController.h"

@interface GTRecommendController ()

@end

@implementation GTRecommendController

- (instancetype) init{
    self = [super init];
    if(self){
        self.tabBarItem.title = @"推荐";
        self.tabBarItem.image = [UIImage imageNamed:@"expore"];
        self.tabBarItem.selectedImage = [UIImage imageNamed:@"expore-active"];
    }
    return self;
}


- (void)viewDidLoad {
    [super viewDidLoad];
     self.view.backgroundColor = [UIColor whiteColor];
    
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    scrollView.backgroundColor = [UIColor lightGrayColor];
    scrollView.contentSize = CGSizeMake(self.view.bounds.size.width * 5, self.view.bounds.size.height);
    
    NSArray *colorArray = @[[UIColor redColor], [UIColor blueColor],[UIColor yellowColor],[UIColor lightGrayColor],[UIColor grayColor]];
    
    for (int i =0; i < 5; i++) {
        [scrollView addSubview:({
             UIView *view =  [[UIView alloc] initWithFrame:CGRectMake(scrollView.bounds.size.width * i, 0, scrollView.bounds.size.width,scrollView.bounds.size.height)];
            view.backgroundColor = [colorArray objectAtIndex:i];
            view;
        })
       ];
      
    }
    // 是否有翻页效果
    scrollView.pagingEnabled = YES;
    [self.view addSubview:scrollView];
}

@end

效果如下:

delegate

objc 复制代码
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
  NSLog(@"开始拖拽");
};

// called on finger up if the user dragged. decelerate is true if it will continue moving afterwards
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
  NSLog(@"结束拖拽");
};

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{
  NSLog(@"开始滚动");
};

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
  NSLog(@"结束滚动");
};

多页面滚动切换

相关推荐
小镇程序员13 分钟前
vue2 src_Todolist全局总线事件版本
前端·javascript·vue.js
野槐15 分钟前
前端图像处理(一)
前端
程序猿阿伟22 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
疯狂的沙粒24 分钟前
对 TypeScript 中函数如何更好的理解及使用?与 JavaScript 函数有哪些区别?
前端·javascript·typescript
瑞雨溪32 分钟前
AJAX的基本使用
前端·javascript·ajax
力透键背35 分钟前
display: none和visibility: hidden的区别
开发语言·前端·javascript
程楠楠&M1 小时前
node.js第三方Express 框架
前端·javascript·node.js·express
盛夏绽放1 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js
想自律的露西西★1 小时前
用el-scrollbar实现滚动条,拖动滚动条可以滚动,但是通过鼠标滑轮却无效
前端·javascript·css·vue.js·elementui·前端框架·html5
白墨阳1 小时前
vue3:瀑布流
前端·javascript·vue.js