UITableView---IOS开发的常用控件使用总结

ew3y 10年前

        UITableView是IOS中非常常见的一个控件,主要用来进行列表内容的展示.有两个默认的内置风格: UITableViewStylePlain和UITableViewStyleGrouped.其中UITableViewStyleGrouped允许将列表中的内容进行分组.UITableViewController是专用于UITableView的视图控制器,提供了一系列的方法来对 UITableView进行创建和维护.

        UITableViewController必须继承两个协议:

1, 通过UITableViewDataSource向UITableView提供数据,向每一个单元格cell进行内容的填充.

2, 通过UITableViewDelegate来处理对于每一个单元格cell的选择事件(如点击选取等).

        常见的注意事项大概如下:

1, 新建UITableViewController子类,并使其继承UITableViewDataSource和UITableViewDelegate协议.

2, 通过storyboard创建UITableView,并将其dataSource和delegate都指向该UITableViewController对象

(storyboard中右键点击UITableView对象,选取并连线即可).

3, 对该UITableView,必须要重写至少两个方法,

        func tableView(table: UITableView, numberOfRowsInSection section: Int) -> Int {   }

        该方法返回tableView中呈现的单元格个数,如return self.products.count

        func tableView(table: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

                let cell = UITableViewCell(style: UITableViewCellStyle.SubTitle, reuseIdentifier: "myCell")

                cell.textLabel.text = self.products[indexPath.row]['title'] as? String

                return cell

        }

        该方法用于描述每一个单元格cell的样式及其中填充的数据,然后返回该cell. 

        每一个cell的基本样式可以通过Identifier来预先设置,如Basic, Subtitle等基本类型, 也可以设置自定义类型myCell.

        let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier("Basic", forIndexPath: indexPath) as UITableViewCell

        该方法从tableView的单元格队列中取出一个cell进行重用.

4, 除了以上两个必须重写的方法之外,设置选取每个cell对应的执行操作,可以通过以下方法,

        func tableView(tableView: UITableView, didSelectRowAtIndex indexPath: NSIndexPath!) { self.didChooseItem(indexPath.row) }

        该方法专用于选取cell时执行的操作.

        func tableView(tableView: UITableView!, willDisplayCell cell: UITableViewCell!, forRowAtIndexPath indexPath: NSIndexPath!) { }

        该方法是在呈现选取该cell时执行的操作,如显示一个警告或者动画.

5, delegate的用法.

        delegate的思想其实很有意思,一个对象做不到的行为,可以给其设置一个代理对象,而代理对象可以代替其完成该行为.

        在UITableView中的使用非常常见.比如从网络中获取数据来填充tableView,我们可以将获取网络数据的操作onRequest封装在一个 HttpController的类中.则获取的数据是跟HttpController的对象绑定在一起的.而我们希望可以直接拿来传递给 tableViewController,而不用通过HttpController对象将数据传递给tableViewController.

        首先,在HttpController中定义一个协议,

        protocol HttpProtocol {

                func parseResults(results: NSDictionary)

        }

        然后,将tableViewController类继承该HttpProtocol协议,并定义parseResults(results: NSDictionary)的函数体.

        接下来,在tableViewController中定义一个HttpController对象,并指定该httpCtl的delegate对象就是该tableViewController自身.

        var httpCtl: HttpController = HttpController()

        httpCtl.delegate = self

        // 这一步对应的是 HttpController类中要定义一个属性 var delegate: HttpProtocol?

        httpCtl.onRequest("www.dianping.com")

        那么,delegate发生作用的过程为,httpController的对象httpCtl调用onRequest方法,onRequest方法中获取到网络数据的原始值,需要调用parseResults方法进行数据解析.而parseResults的函数体是在 tableViewController中定义的.则最终过程为,在httpCtl.onRequest中使用 self.delegate?.parseResults(jsonResult)即可对网络数据进行解析.同时,解析的数据在parseResults 函数体中即可直接传递给tableViewController(传递过程即为,直接赋值给tableViewController的属性如 products数组即可).

        以上,就是delegate发生作用的基本过程.描述不清楚的地方,欢迎各位同学一起来探讨.

        其实,不采用delegate的方式也可以实现上述功能,即将parseResults函数体直接定义为HttpController自身的方法,则获取网络数据和解析网络数据都在HttpController中完成.最后通过segue等方式将数据从HttpController中传递给 tableViewController即可.但涉及到更加复杂的数据传递或者操作,还是推荐使用delegate的思想来实现.