美文网首页iosIOS三人行iOS Developer - UITableView
static cell 与 dynamic cell 混合使用

static cell 与 dynamic cell 混合使用

作者: Chakery | 来源:发表于2016-09-05 16:41 被阅读2353次

    demo中的master分支是基于Xcode7.3,swift2.2
    如果使用Xcode8.0,swift3.0,请选择swift3.0分支
    【 view on GitHub 】 如果你觉得有用,麻烦顺手给个star,满足一下笔者的虚荣心。

    关于静态cell与动态cell的混合使用,google一下便会有很多相关文章,这里也是看过一些前辈的经验(已经忘记具体是从哪篇文章得到的帮助)之后自己做的笔记。

    在某些界面中static cell与dynamic cell混合使用会事半功倍,比如手机上的Wi-Fi功能等,效果图如下:

    Wi-Fi

    Wi-Fi界面的第一组与第三组的行数都是固定的,且布局并不相同,类似这样的布局使用static cell很快就可以完成,然而第二组却需要使用dynamic cell。这时候就会用到静态cell与动态cell混合使用的情况。

    首先,在Storyboard中添加一个UITableViewController,设置为Static cell,并设置好第一组与第三组的内容,第二组需要设置一个空的Cell,如图:

    UITableViewController

    然后,给第二组的空白Cell设置identifier值,如图:

    设置identifier

    然后,第二组需要自定义cell,这里使用XIB来完成,如图:

    dynamic cell

    接下来需要用代码注册Nib,如下:

    let nib = UINib(nibName: "WiFiTableViewCell", bundle: nil)
    tableView.registerNib(nib, forCellReuseIdentifier: "WiFiTableViewCell")
    

    最后,为了让 static cell 与 dynamic cell 能够混合使用,需要实现TableView的代理,代码如下:

       // 以下代理方法必须实现
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      if indexPath.section == 1 {
        let cell = tableView.dequeueReusableCellWithIdentifier("WiFiTableViewCell") as? WiFiTableViewCell
        return cell!
      }
      return super.tableView(tableView, cellForRowAtIndexPath: indexPath)
    }
        
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
      if section == 1 {
        return 10 //这里返回第二组的行数
      }
      return super.tableView(tableView, numberOfRowsInSection: section)
    }
        
    override func tableView(tableView: UITableView, indentationLevelForRowAtIndexPath indexPath: NSIndexPath) -> Int {
      if indexPath.section == 1 {
        return super.tableView(tableView, indentationLevelForRowAtIndexPath: NSIndexPath(forRow: 0, inSection: 1))
      }
      return super.tableView(tableView, indentationLevelForRowAtIndexPath: indexPath)
    }
        
    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
      if indexPath.section == 1 {
        return 44
      }
      return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
    }
    

    值得注意的是:

    • 在storyboard中需要给第二组设置一行空的Cell,并设置identifier值。
    • 在代码中也需要注册Cell
    • 上面提到的代理方法必须实现

    最后,本文主要是记录关于 static cell 与 dynamic cell 的混合使用,因此很多细节问题并没有处理,更多关于static cell另外的一些使用,可以点击这里【更优雅地使用Static Cell】

    相关文章

      网友评论

      • Jobscn:如果我不用TableViewController,用的ViewController然后拖入TableView,就没办法用super.tableView()了,怎么解决咧
        Chakery:你可以使用container view来指向tableviewController
        Chakery:直接用table view 不行
      • 流年_橙子:作者 作者 @Chakre 为啥要重写 heightForRowAtIndexPath 和indentationLevelForRowAtIndexPath 这2个方法呢 求告知
        Hello_kid:@流年_橙子 其实我也没明白这俩句话
        流年_橙子:@Ruiz678 谢谢
        Hello_kid:当覆盖storyboard中的staticcell时,因为数据源对新加进来的cell一无所知,所以需要写这个代理方法。否则会导致崩溃
      • zhangqi0431:问题解决,参考了别人的留言,要在storyboard里设置section,不过可以设置24以上,我设置了30,也就是说真实数据超过三十会崩溃。我是为了模仿饿了么的提交订单页面。
      • zhangqi0431:大神求助,我用swift3.0,在numberOfRowsInSection方法里return 1 就没问题,但是return多行就报错。求指点。
        Chakery:@zhangqi0431 刚迁移到swift3.0,并没有出现你说的问题。代码请看swift3.0分支。
        https://github.com/Chakery/StaticAndDynamicExample/tree/swift3.0
      • zhw511006:你的例子报这个错误!
        Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/Moonlight/Library/Developer/CoreSimulator/Devices/D25637F5-6FB3-476D-8FD9-F734A6C53017/data/Containers/Bundle/Application/ACD286BE-29F9-4691-8704-264419E3668F/StaticAndDynamicExample.app> (loaded)' with name '<StaticAndDynamicExample.WiFiTableViewCell: 0x7fe890005800; baseClass = UITableViewCell; frame = (0 0; 320 44); layer = <CALayer: 0x60000003c0c0>>''
        zhw511006:@Chakery 我的nib能加载正常,但是就是报runlop的错;如果我在storyboard里面把空行所在的section设置为24,因为动态行最多24个;就正常了!不知道什么原因!
        Chakery:@zhw511006 我这边并没有出现你说的问题。如果出现问题的话,你可以去掉xib,用代码来写。
        Chakery:@zhw511006 这应该是xib的加载出现了问题,demo是使用Xcode7.3创建的。
      • zhw511006:我这边报这个错误!
        invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.
      • i_Fancy:大神,求助
      • i_Fancy:- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

        if (section == 1) {
        return 6;
        }

        return [super tableView:tableView numberOfRowsInSection:section];
        }

        报数组越界错误,难不成return的个数要小于在storyboard中创建空白cell行数吗?貌似不太科学
        *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSSingleObjectArrayI objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
        iOS开发周立贺:@i_Fancy 和你的问题一样啊 但是重写了indentationLevelForRowAtIndexPath 还是越界啊
        i_Fancy:@Chakery OK,已经解决了,就是这个方法没有重写,感谢
        Chakery:@忆中微笑如你 其他的方法你有重载么?比如:`indentationLevelForRowAtIndexPath `等,或者你能贴完整一点的代码么。

      本文标题:static cell 与 dynamic cell 混合使用

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