可展开的UITableView (附源码)
程序员文章站
2022-06-03 12:45:31
...
由于工作需要,写了一个UITableView的子类,简单的实现了每个cell的展开和收缩的动画效果以及展开和收缩后的cell样式变化。这个效果也许你现在用不到,但是它在iOS上的效果确实很不错,也许以后你就会用到。分享给大家。给大家一个实际的效果:
ExtensibleTableView.h
ExtensibleTableView.m
将这2个文件放到proj之后,要设置delegate_extend并且实现
//返回展开之后的cell
- (UITableViewCell *)tableView:(UITableView *)tableView extendedCellForRowAtIndexPath:(NSIndexPath *)indexPath;
//返回展开之后的cell的高度
- (CGFloat)tableView:(UITableView *)tableView extendedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
2个方法。
还有一点不合理的地方,我试着去解决,但是最终未果=。=!
这里要先判断当前行是否被选中,若被选中则调用extendedCellForRowAtIndexPath方法。因为我试着重写UITableView的- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath方法。试图在这个方法里做上边的事情,可是这个方法总是在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法之前被调用,因此没有达到预期的目标。
希望各位如果下载了源码,解决了这个问题的话,可以回到这里给我留言或者联系qq82934162.
以下是一个简单的demo源码:
http://dl.iteye.com/topics/download/4f242bbb-8004-3352-9604-b1211b7562df
ExtensibleTableView.h
// // ExtensibleTableView.h // Wow // // Created by Boris Sun on 12-6-20. // Copyright (c) 2012年 adsit. All rights reserved. // #import <UIKit/UIKit.h> @protocol ExtensibleTableViewDelegate <NSObject> @required //返回展开之后的cell - (UITableViewCell *)tableView:(UITableView *)tableView extendedCellForRowAtIndexPath:(NSIndexPath *)indexPath; //返回展开之后的cell的高度 - (CGFloat)tableView:(UITableView *)tableView extendedHeightForRowAtIndexPath:(NSIndexPath *)indexPath; @end @interface ExtensibleTableView : UITableView { //当前被展开的索引 NSIndexPath *currentIndexPath; id<ExtensibleTableViewDelegate> delegate_extend; } @property(nonatomic,retain)id delegate_extend; @property(nonatomic,retain)NSIndexPath *currentIndexPath; //将indexPath对应的row展开 - (void)extendCellAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated goToTop:(BOOL)goToTop; //将展开的cell收起 - (void)shrinkCellWithAnimated:(BOOL)animated; //查看传来的索引和当前被选中索引是否相同 - (BOOL)isEqualToSelectedIndexPath:(NSIndexPath *)indexPath; @end
ExtensibleTableView.m
// // ExtensibleTableView.m // Wow // // Created by Boris Sun on 12-6-20. // Copyright (c) 2012年 adsit. All rights reserved. // #import "ExtensibleTableView.h" @implementation ExtensibleTableView @synthesize delegate_extend; @synthesize currentIndexPath; - (id)init { currentIndexPath = nil; return [super init]; } //重写设置代理的方法,使为UITableView设置代理时,将子类的delegate_extend同样设置 - (void)setDelegate:(id<UITableViewDelegate>)delegate { self.delegate_extend = delegate; [super setDelegate:delegate]; } /* 将indexPath对应的row展开 params: animated:是否要动画效果 goToTop:展开后是否让到被展开的cell滚动到顶部 */ - (void)extendCellAtIndexPath:(NSIndexPath *)indexPath animated:(BOOL)animated goToTop:(BOOL)goToTop { NSLog(@"debug 2"); //被取消选中的行的索引 NSIndexPath *unselectedIndex = [NSIndexPath indexPathForRow:[currentIndexPath row] inSection:[currentIndexPath section]]; //要刷新的index的集合 NSMutableArray *array1 = [[NSMutableArray alloc]init]; //若当前index不为空 if(currentIndexPath) { //被取消选中的行的索引 [array1 addObject:unselectedIndex]; } //若当前选中的行和入参的选中行不相同,说明用户点击的不是已经展开的cell if(![self isEqualToSelectedIndexPath:indexPath]) { //被选中的行的索引 [array1 addObject:indexPath]; } //将当前被选中的索引重新赋值 currentIndexPath = indexPath; if(animated) { [self reloadRowsAtIndexPaths:array1 withRowAnimation:UITableViewRowAnimationFade]; } else { [self reloadRowsAtIndexPaths:array1 withRowAnimation:UITableViewRowAnimationNone]; } if(goToTop) { //tableview滚动到新选中的行的高度 [self scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; } } //将展开的cell收起 - (void)shrinkCellWithAnimated:(BOOL)animated { //要刷新的index的集合 NSMutableArray *array1 = [[NSMutableArray alloc]init]; if(currentIndexPath) { //当前展开的cell的索引 [array1 addObject:currentIndexPath]; //将当前展开的cell的索引设为空 currentIndexPath = nil; [self reloadRowsAtIndexPaths:array1 withRowAnimation:UITableViewRowAnimationFade]; } } //查看传来的索引和当前被选中索引是否相同 - (BOOL)isEqualToSelectedIndexPath:(NSIndexPath *)indexPath { if(currentIndexPath) { return ([currentIndexPath row] == [indexPath row]) && ([currentIndexPath section] == [indexPath section]); } return NO; } /* 重写了这个方法,却无效,因为这个方法总在didSelect之前调用,很奇怪。因为无法重写该方法,所以ExtensibleTableView不算完善,因为还有额外的代码需要在heightForRowAtIndexPath和cellForRowAtIndexPath中。哪个找到完善的方法后希望可以与qq82934162联系或者在http://borissun.iteye.com来留言 */ //- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath //{ // if([currentIndexPath row] == [indexPath row]) // { // return [self.delegate_extend tableView:self extendedCellForRowAtIndexPath:indexPath]; // } // return [super cellForRowAtIndexPath:indexPath]; //} - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if([currentIndexPath row] == [indexPath row]) { return [self.delegate_extend tableView:self extendedHeightForRowAtIndexPath:indexPath]; } return [super rowHeight]; } @end
将这2个文件放到proj之后,要设置delegate_extend并且实现
//返回展开之后的cell
- (UITableViewCell *)tableView:(UITableView *)tableView extendedCellForRowAtIndexPath:(NSIndexPath *)indexPath;
//返回展开之后的cell的高度
- (CGFloat)tableView:(UITableView *)tableView extendedHeightForRowAtIndexPath:(NSIndexPath *)indexPath;
2个方法。
还有一点不合理的地方,我试着去解决,但是最终未果=。=!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //若当前行被选中,则返回展开的cell if([tableView_ isEqualToSelectedIndexPath:indexPath]) { return [self tableView:tableView extendedCellForRowAtIndexPath:indexPath]; } ... }
这里要先判断当前行是否被选中,若被选中则调用extendedCellForRowAtIndexPath方法。因为我试着重写UITableView的- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath方法。试图在这个方法里做上边的事情,可是这个方法总是在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath方法之前被调用,因此没有达到预期的目标。
希望各位如果下载了源码,解决了这个问题的话,可以回到这里给我留言或者联系qq82934162.
以下是一个简单的demo源码:
http://dl.iteye.com/topics/download/4f242bbb-8004-3352-9604-b1211b7562df
上一篇: 枇杷果的功效和作用
推荐阅读
-
CSS3实现的闪烁跳跃进度条示例(附源码)
-
使用DevExpress的PdfViewer实现PDF打开、预览、另存为、打印(附源码下载)
-
基于DevExpress的SpreadsheetControl实现对Excel的打开、预览、保存、另存为、打印(附源码下载)
-
详解可跨域的单点登录(SSO)实现方案【附.net代码】
-
JSP实用教程之简易图片验证码的实现方法(附源码)
-
JSP实用教程之简易文件上传组件的实现方法(附源码)
-
JSP实用教程之简易页面编辑器的实现方法(附源码)
-
jQuery插件实现的日历功能示例【附源码下载】
-
Python基于pygame实现的弹力球效果(附源码)
-
python中pygame针对游戏窗口的显示方法实例分析(附源码)