教你写个多表视图

作者: Sheepy | 来源:发表于2015-12-28 18:11 被阅读2361次
multi_table.gif

如图所示的多表视图是一个很常用的东西,之前我是用UIScrollViewUITableViewController做的。把当前的控制器作为一个父控制器,添加三个UITableViewController的实例作为子控制器,把父控制器中的 scrollView 作为容器,然后添加子控制器中的 tableView 作为子视图。这样做有一个问题,一旦有十几二十个表的话,内存就要爆炸了。解决的办法是可以自己写个重用机制,不过这显然没必要,用自带重用机制的UICollectionView应该是个更好的选择。

首先新建个HomeContainerViewController,继承自UICollectionViewController,然后在viewDidLoad里面加上这两句:

collectionView?.pagingEnabled = true
collectionView?.bounces = false

这样滑动的时候就会有翻页的段落感,滑到边界的时候也不会有回弹效果。

然后要用 layout 控制布局,用最常用的 UICollectionViewFlowLayout 就行了,设置单元格的宽高,既然是翻页,宽肯定是跟屏幕等宽,高度就看你需求了,但是不要超过 collectionView 的高,如下:

lazy var layout: UICollectionViewFlowLayout = {
    let lazyLayout = UICollectionViewFlowLayout()
    lazyLayout.itemSize = CGSize(width: Width, height: Height)
    lazyLayout.minimumInteritemSpacing = 0
    lazyLayout.minimumLineSpacing = 0
    lazyLayout.scrollDirection = .Horizontal
    return lazyLayout
}()

之后就可以用这个 layout 来初始化之前定义的HomeContainerViewController。接下来我们要自定义一个UICollectionViewCell,让它包含一个 tableView:

class HomeCollectionViewCell: UICollectionViewCell {
    
    var tableView: UITableView!
    var dataSource: HomeTableDataSource!
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        tableView = UITableView(frame: bounds, style: .Grouped)

        tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: CellReuseIdentifier.LatestArticles)
        addSubview(tableView)

        dataSource = HomeTableDataSource()
        tableView.dataSource = dataSource
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }  
}

这边还有一个 dataSource(同理可自行添加 delegate),是 tableView 的数据源,可能大部分人习惯把控制器又当 dataSource 又当 delegate,不过我比较喜欢分开,就算是用同一个控制器,也会用extension把代码分开。好现在我们看看如何定义这个 dataSource:

class HomeTableDataSource: NSObject, UITableViewDataSource {

    var cellData: String?
    
    func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 20
    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return 1
    }

    
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier(CellReuseIdentifier.LatestArticles, forIndexPath: indexPath)

        //Configure the cell...
        cell.textLabel?.text = cellData
        return cell
    }
}

注意一定要继承 NSObject ,因为 UITableViewDataSource协议是继承了NSObjectProtocol协议的,所以如果你不继承NSObject的话,还得自己写一堆方法来遵守NSObjectProtocol协议。因为这边只是个 Demo,所以我直接在 cell 中显示cellData的值,那cellData 的值在哪里设置呢?显然是在HomeContainerViewController中:


let tableViewDataList = ["first table", "second table", "third table"]
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! HomeCollectionViewCell
    
    // Configure the cell
    cell.dataSource.cellData = tableViewDataList[indexPath.section]
    cell.tableView.reloadData()
    
    return cell
}

在真实场景中一般是会在 dataSource 中放一个 urlString 的属性,然后一旦这个属性被赋值就自动联网取数据。这边 cell 是会被复用的,在翻到第三页时,会复用第一页的 cell ,第四页复用第二页的 cell……依此类推,所以需要给 cell 中的tableView调用 reloadData方法,不然就算改变了表中的数据,也不能正确的显示(奇数页都显示第一页的数据,偶数页都显示第二页的数据)。

这样就完成了一个多表视图,实际项目一般会在 table 上方放个小滑块指示器什么的,也很简单,只要在cellForItemAtIndexPath方法中根据indexPath.section来设置滑块位置就好了。

相关文章

  • 教你写个多表视图

    如图所示的多表视图是一个很常用的东西,之前我是用UIScrollView和UITableViewControlle...

  • oracle新建视图

    视图其实就是一条查询语句,如果我们经常需要多表关联查询一些数据,那么不妨建一个视图,以后操作该视图就相当于操作多表...

  • Mysql多表查询, 视图,事务,索引,函数,go连接数据库

    1.1 今日目标 理解多表查询 理解子查询 能够创建视图 能够删除视图 能够查看创建视图的SQL语句 能够理解事...

  • mysql 视图

    使用视图的好处 视图是多表联合的结果,避免代码重复 视图更安全,用户只能访问到视图给定的内容集合,比如多租户模式的...

  • thinkphp v5 视图查询

    视图查询可以实现不依赖数据库视图的多表查询,并不需要数据库支持视图 注意,视图查询无需调用table和join方法...

  • iOS - UIView的clipsTobounds属性和mas

    clipsToubounds:如果子视图的范围超出了父视图的边界,那么超出的部分就会被裁剪掉。写个Demo看看效果...

  • power pivot创建多表连接

    调出关系图视图,创建多表连接创建多表连接时,如果要将来自不同表的不同值进行对比,则需要将这两个表共同作为箭头起点的...

  • 创建多表查询的结果视图

    存在多个表都有相同的一个字段a,但是数据在表中参差不齐,现在有一个需求,创建一个视图,包含多表查询的所有结果,表中...

  • mysql复杂查询--多表查询

    多表查询 多表查询是指基于两个和两个以上的表或是视图的查询.在实际应用中,查询单个表可能不能满足你的需求,(如显示...

  • 书籍展示----2.书籍列表显示

    前言 本节和类别逻辑差不多。创建视图模板文件->在视图控制器中写方法->在类别的ajax写个页面跳转->加个路由-...

网友评论

  • 小杨的app:来个demo
  • 溪枫狼:我最近做了一个类似的界面,上面一排collectionview加滑动的线条,下面scrollview添加子视图控制器的view。缺点是一次性加载完,耗内存,极少数情况下滚动完了不会触发已经减速的代理方法。有可能出现内存泄露,子视图控制器没法顺利释放掉。楼主的思路蛮好,还有种思路是横着的tableview,有点折腾。
    Sheepy:@Flyme溪枫狼 我也用scrollview实现过,复用逻辑也可以自己写,后来发现完全没必要,用collectionview方便多了,自带复用机制。同样的思路用collectionview实现图片轮播什么的也很方便。话说横过来的tableview什么鬼,脑洞好大😁不过我觉得collectionview是比tableview更通用的一种视图,因为完全可以简单设置collectionview的layout来达到普通tableview的效果,反过来就有些麻烦。
  • 00fe1d42e006:手动点赞:relaxed:
    Sheepy:@迷糊小小姐 (^_^)

本文标题:教你写个多表视图

本文链接:https://www.haomeiwen.com/subject/luobhttx.html