从08年到如今开发过的iOS应用不可胜数了,可是面试不少人的时候,发现依然不少同窗在最基本的列表控件上懂得不够深,下面就结合各方面的资料进行再一次讲解。面试
咱们都知道纯代码是效率最高的,可是在开发成本上已经愈来愈不如使用Storyboard性价比高,速度快,因此本文试图结合UIStoryboard来描述一整套方案。segmentfault
在Storyboard中拖入UITableViewController,而且修改涂涂画画。xcode
在代码区new File生成一个基于UITableviewController的自定义类,我这里暂时取名为Home。由于主页就是一个复杂的列表的不在少数吧?呵呵。网络
而后在Identity insepctor里修改对应的Class name,使得代码与Storyboard产生关联。函数
想要作下拉刷新嘛?系统自带了一个给你,而且能够自定义换标题哦。不少人真的不知道在哪儿选中,请看下图,先选中UITableviewController,而后在选项卡中enable这个refresh选项,就自动完成了。 对应的代码仍是复制进去,就会自动触发。优化
而后你须要对UITableView作一些简单的配置,首先要选中UITableView,不少人看不到选项,是由于默认关闭了……ui
下图是对UITableview的简单配置。atom
Content是动态列表/静态列表,若是是静态的,那你基本不用写代码就能所见即所得,譬如“设置”页面就能够套用。可是诸如微博啦,朋友圈,仍是老实的用动态列表,用代码控制。url
Prototype Cells指会出现的cell有几种类型。这个后面再讲。spa
Style效果现场试一下就看出来了。Separator指的分隔行样式。
而后你就须要代码中作一些简单的配置了,我只列重要的,这里不是基础教程,基础的仍是老实的看教科书
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView //几组 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section//每一组分别几行 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath//每一行多高 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath//每一行分别长啥样 -(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath//即将显示某行
加载更多的UITableview扩展控件很是多,尝试过各类第三方完美扩展后,我以为这点小把戏也不至于须要扩展UITableview类吧?
那就是在列表追加一个Section,放在最后面,这个Section只有一个Cell,这个自定义的cell有3种状态,这些均可以自由发挥。
每当willDisplayCell的时候,你就设置他正在loading状态,给用户形成正在加载的假象,同时触发网络请求。
当有网络数据返回后,天然会insert好多内容,也轮不到这个加载更多的cell显示的地方了,天然就释放了。固然了,若是没有更多内容,也能够轻松的cellForRowAtIndexPath找到惟一的cell,设置为无更多数据等状态。
typedef enum{ JWLoadMoreNormal = 0,//点击再加载 JWLoadMoreLoading,//加载中 JWLoadMoreDone,//无更多数据 } JWLoadMoreState; @interface LoadMoreCell : UITableViewCell @property (strong, nonatomic) UIView *baseWhiteView; @property (strong, nonatomic) UIActivityIndicatorView *activity; @property (strong, nonatomic) UILabel *tipsLabel; @property (strong, nonatomic) UIButton *loadMoreButton; @property (nonatomic,unsafe_unretained) id <LoadMoreCellDelegate> delegate; -(void)setupUI; - (void)loadMore:(id)sender; -(void)setLoadMoreStatus:(JWLoadMoreState)status;
作完这些,基本配置就完成了,下面须要根据设计师的要求进行自定义开发,譬如自定义cell
如上图,密密麻麻的
autolayout的拖拽不会?你太老土了吧。xcode5的拖拽,可谓是异常简单,只须要点快捷菜单的pin,设置好上下左右相对关系就能够了。
建立custom的uitableviewcell基本差很少,拖出来,画画涂涂,建立代码,改类名对应关系,按着“Control”拖拽关联,等等。
我这里只讲一个特殊的,就是图上“图片”“摘要”属于并排区域,可能没有图片的帖子,“摘要”就须要顶格排版。这样的状况该怎么设置呢?
这就得用NSLayoutConstraint的拽出来的关联了。把”摘要“的相对距离,锁定在一个固定的位置上,譬如”左边栏“,经过少许的代码计算,便可动态的修改NSLayoutConstraint.constant的距离。
NSString *url=data.img; [self.previewImageView setClipsToBounds:YES]; if ( url!=nil && ![url isEqualToString:@""]) { //这里是判断有图没图 [self.previewImageView setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"pic_default"]]; self.previewImageHeight.constant=HomeCellImageHeight; self.previewImageWidth.constant=HomeCellImageWidth; self.abstractLeftMargin.constant=10; //如有图,摘要与图的左边距变为10 self.summaryDistanceBetweenTitle.constant=80; } else { [self.previewImageView setImage:nil]; self.previewImageHeight.constant=0; //图片大小全清空为0 self.previewImageWidth.constant=0; self.abstractLeftMargin.constant=0; //若无图,摘要与图的左边距变为10 } [self setNeedsUpdateConstraints]; //记得强制刷新,要否则系统懒懒的 [self.contentView layoutIfNeeded]; [self.contentView setNeedsLayout];
作到这里,恐怕大部分人都遇到一个门槛了。那就是如何动态计算cell的高度。最简单的,就是网易新闻类,固定高度。return 44;
如果动态的,无非是建立一个cell,而且初始化构造好,而后输出cell的最后一行控件的位置,最终给出位置。
可是这就致使了函数运行的低效。你想,autolayout原本就够效率低了(由于程序猿省事儿了),再为每一行计算2次,这效率能高?
我亲测发现,动态排版效率是很是低的,不足以信任。
最好办的,仍是土方法。获取对应的数据,根据本身设定的排版规则,动态的计算。土归土,效率高啊!
TopicID *data=[threadList objectAtIndex:indexPath.row]; // NSLog(@"计算行数为%d",indexPath.row); int height=0; height+=17; //用户名与顶部空间 height+=17; //用户名高度 height+=8; //用户名与标题之间距离 NSString *titleContent=data.title; UIFont *titleFont = [UIFont boldSystemFontOfSize:16.0]; CGSize titleRealSize=[titleContent sizeWithFont:titleFont constrainedToSize:CGSizeMake(280, 150) lineBreakMode:NSLineBreakByTruncatingTail]; height+=titleRealSize.height;//动态计算标题高度 if (data.img!=nil && ![data.img isEqualToString:@""]) { height+=HomeCellImageHeight;//统计图的起始点 height+=20; // NSLog(@"有图"); } else { NSString *abstract=data.abstract; UIFont *abstractFont = [UIFont boldSystemFontOfSize:14.0]; CGSize abstractRealSize=[abstract sizeWithFont:abstractFont constrainedToSize:CGSizeMake(280, 300) lineBreakMode:NSLineBreakByTruncatingTail]; height+=abstractRealSize.height; height+=20; // NSLog(@"无图"); } height+=56; //统计图的高度 height+=3;//下边框的高度
最后别忘了Profile,计算时间,每个细节的时间优化,最终都会体如今列表的流畅度表现上。 经过以上几点呢,再结合现成好用的SDWebImageCache,相信你们必定能够作出真正美观、高效的列表哦!