注:我们发布这个框架上GitHub上

UITableView的是事实上的工具来帮助我们发展我们的iOS应用程序时创建的细胞行。的典型配置由具有的NSObject的(多个)符合UITableViewDataSource的UITableViewDelegate协议,执行样板所需的方法,然后注册必要的UITableViewHeaderFooterView的UITableViewCell类型与UITableView的

当配置就足够了大部分的时间,尤其是你的UITableView的仅由单一细胞类型的,但如果我们要处理更复杂的结构会发生什么?如果我们的UITableView的是与各种动作和高度,以由10+细胞类型,自定义部分页眉/页脚视图?逻辑来决定如何处理的数据源/委托方法实施中的每个案件将很快得到手了。

内OkCupid的应用188bet金宝搏官网程序,我们正在面对这类情况不断。下面是一个典型的实现可能会发现的例子UITableViewDataSourceFUNC的tableView(_的tableView:UITableView的,cellForRowAt indexPath:IndexPath) - >的UITableViewCell

类AdvertisementCell:的UITableViewCell {}类MatchCell:的UITableViewCell {}类QuestionCell:的UITableViewCell {}协议模型{}结构广告:型号{} STRUCT匹配度:模型{}结构问题:模型{} FUNC的tableView(_的tableView:UITableView的,cellForRowAt indexPath:IndexPath) - >的UITableViewCell {让模型=模型[indexPath.item]要是让广告=模型?广告{//出队,配置和返回AdvertisementCell}否则如果再让匹配=模型?比赛{//出队,配置和返回MatchCell}否则,如果让问题=模型?提问{//出队,配置和回报QuestionCell}}

随着我们继续添加更多的型号类型产生对应显示的UITableViewCellS,我们的代码线性增长。每种情况下,都有自己独立的出列和配置逻辑。这种模式可以使我们的代码非常困难的原因有关,并难以维持我们引进了多个模型/的细胞类型。

通过简单的数据源/委托方法中定义我们的逻辑实现UITableViewDataSource /的UITableViewDelegate在我看来不足为多细胞/模型类型配置。考虑到这一点,我着手创建一个抽象的,这将有助于我实现UITableView的■在一个更简单的方法。

介绍OKTableViewLiaisonOKTableViewLiaison是抽象了所有传统的框架UITableViewDataSource的UITableViewDelegate样板,让你有一个清晰的,模块化和可扩展的API为您打造您的UITableView的秒。

该框架围绕与单个对象进行交互时,OKTableViewLiaison,该发动机罩符合下UITableViewDataSource的UITableViewDelegate协议和手柄插入,删除,并在行和部分移动你UITableView的

为了说明的力量OKTableViewLiaison,我要一步一步教你如何建立一个Instagram的/ reddit的内容一样的饲料,只需使用UITableView的UITableViewHeaderFooterView的UITableViewCellS和OKTableViewLiaison框架。

首先让我们来创建一个新的单一视图应用项目使用迅速Xcode中。最简单的方法,将OKTableViewLiaison到你的项目是通过的CocoaPods

荚“OKTableViewLiaison”

迦太基即将支持。

我们的饲料是要显示文章的集合,其中每个由谁创建的报头表示,在图像的形式的片的内容,一组的操作按钮和文本说明字幕的图像,总金额的意见和喜欢接收到请求,并创建职位时的时间戳。

截屏,2018年5月17日,在-11.51.21-AM

我们可以通过创建以下的Structs我们的岗位模型:

结构用户{让用户名:字符串让头像:UIImage的}
结构帖子{让用户:用户让内容:UIImage的让numberOfLikes:UINT让标题:字符串让numberOfComments:UINT让timePosted:} TimeInterval所

为了确保最大的可重用性和我们的UI的灵活性,让代表岗位作为UITableView的部,其中每个组件可以是一个UITableHeaderFooterView要么的UITableViewCell。通过这种方式,而不是建立一个邮政作为一个巨大的的UITableViewCell我们可以重新排序,删除和添加的组件产品需求的变化。

我们的后段都将有一个自定义标题视图,PostTableViewSectionHeaderView,那简直是要包含一个UIImageView和的UILabel显示头像和用户名。

截屏,2018年5月17日,在-11.50.12-AM

截屏,2018年5月17日,在-11.57.1​​3-AM

最后一类PostTableViewSectionHeaderView:UITableViewHeaderFooterView {@IBOutlet弱VAR ImageView的:UIImageView的!@IBOutlet弱VAR titleLabel:的UILabel!重写FUNC awakeFromNib(){super.awakeFromNib()imageView.layer.masksToBounds =真imageView.contentMode = .scaleAspectFit}覆盖FUNC layoutSubviews(){super.layoutSubviews()imageView.layer.cornerRadius = imageView.frame.height / 2}}

OKTableViewLiaison表示使用该补充的页眉/页脚的观点类OKTableViewSectionComponent <查看:UITableViewHeaderFooterView,型号>类型。

OKTableViewSectionComponent利用两个泛型类型:

查看:UITableViewHeaderFooterView是类型UITableViewHeaderFooterView用于视图。
模型是用来帮助一个类型配置视图。

现在,我们有自定义节头,让我们创建我们的组件为的子类OKTableViewSectionComponent

最后一类PostTableViewSectionHeaderViewComponent:OKTableViewSectionComponent  {公共的init(用户:用户){super.init(用户,registrationType:PostTableViewSectionHeaderViewComponent.defaultNibRegistrationType)组(高:.height,70)组(命令:.configuration){视图,用户,在第view.imageView.image = user.avatar view.imageView.layer.borderColor = UIColor.gray.cgColor view.imageView.layer.borderWidth = 1 view.titleLabel.text = user.username view.titleLabel.font =.systemFont(ofSize:13,重量:.medium)view.titleLabel.textColor =。黑}}}

我们首先声明PostTableViewSectionHeaderViewComponent作为一个子类OKTableViewSectionComponent

然后,我们继续来定义我们的初始化,这需要用户实例作为参数。在我们的初始,我们做一个呼叫super.init我们还通过在OKTableViewRegistrationType

OKTableViewRegistrationType是表示如何枚举OKTableViewLiaison要注册的UITableViewCell要么UITableViewHeaderFooterView与A型UITableView的。由于我们创建了PostTableViewSectionHeaderView用一个厦门国际银行, 然后厦门国际银行名字是一样的它的相关类,我们可以简单地传递.defaultNibRegistrationType作为OKTableViewRegistrationType

最后,我们设置了标题的高度,并定义其。组态关闭。OKTableViewSectionComponentCommand代表我们的页眉/页脚意见生命周期事件。该命令关闭我们定义通过实例我们视图中,模型对象,并且该部分的内的索引UITableView的。该。组态关闭每次出队的UITableView的部分补充视图时间将被调用。

现在,PostTableViewSectionHeaderViewComponent已经被定义,让我们开始构建我们的邮政行。要使用创建一行OKTableViewLiaison我们使用以下类型:

类OKTableViewRow <细胞:的UITableViewCell,型号>

如同OKTableViewSectionComponentOKTableViewRow利用两个泛型类型:

手机:UITableViewCell的是用于行的UITableViewCell的类型。
模型是用来帮助一个类型的单元配置为行。

在节中给出的第一行是为内容图像。在这里,我们要创建一个包含固定到其边缘单一的UIImageView一和的UITableViewCell。

截屏,2018年5月17日 - 在 -  23年1月18日,PM

截屏,2018年5月17日 - 在 -  51年1月21日,PM

最后一类ImageTableViewCell:{UITableViewCell的弱@IBOutlet VAR contentImageView:UIImageView的!}
最后一类ImageTableViewRow:OKTableViewRow  {的init(图像:UIImage的,宽度:CGFloat的){super.init((图像,宽度),registrationType:ImageTableViewRow.defaultNibRegistrationType)组(高:.height){模型 - > CGFloat的在设(图像,宽度)=模型让比= image.size.width / image.size.height返回宽度/比率}集(命令:.configuration){细胞,型号,indexPath在cell.contentImageView。图像= model.0 cell.contentImageView.contentMode = .scaleAspectFill}}}

类的声明对我们的定制OKTableViewRow颇为相似,我们的OKTableViewSectionComponent

我们定义一个初始化采用两个参数,一个UIImage和表示的宽度的CGFloat的UITableView的(更多在第二宽度)。

而是通过一个静态值,以确定我们的单元格的高度,我们采用闭合计算的高度。这样做的目的是为了维护每个内容图像正确的纵横比。通过传递我们的UITableView的宽度,我们可以推导出正确的高度。

最后,我们通过设置配置我们的细胞。组态关闭。封闭件穿过的一个实例细胞, 它的模型对象和IndexPath排。

有超过15个不同OKTableViewRowCommand事件可以为包括设置关闭didSelect删除插入移动重装

接下来,我们将实现一个假动作按钮行显示像,评论,分享和书签功能,使用表情符号!

截屏,2018年5月17日,在-4.50.04-PM

截屏,2018年5月17日,在-4.47.52-PM

最后一类ActionButtonsTableViewCell:{UITableViewCell的弱@IBOutlet VAR likeButton:UIButton的!@IBOutlet弱VAR commentButton:UIButton的!@IBOutlet弱VAR messageButton:UIButton的!@IBOutlet弱VAR bookmarkButton:UIButton的!}
最后一类ActionButtonsTableViewRow:OKTableViewRow  {的init(){super.init((),registrationType:ActionButtonsTableViewRow.defaultNibRegistrationType)组(高:.height,30)组(命令:.configuration){细胞,_,_在cell.likeButton.setTitle( “❤️”,为:。中性)cell.commentButton.setTitle( “”,为:。中性)cell.messageButton.setTitle( “”,为:。中性)cell.bookmarkButton.setTitle(“”,为:。中性)cell.selectionStyle = .none}}}

我们的帖子的最后部分是文本。我们可以分解文成四个不同的行;喜欢,标题,注释和时间。除了文本颜色,字体和实际的文字,每行之间的唯一真正的区别是它们的高度。以前我们设置每行的高度使用静态值或封闭计算它。在这种情况下,我们需要高度基于其文本的大小是动态的。没问题!默认情况下,OKTableViewRow将返回的高度UITableViewAutomaticDimension如果没有指定的,使我们能够建立我们的的UITableViewCell是自调整大小。我们也可以另外设置使用行预测的高度OKTableViewHeightType.estimatedHeight如果需要的话。

截屏,2018年5月17日,在-5.50.45-PM

截屏,2018年5月17日,在-5.51.18-PM

最后一类TextTableViewCell:{UITableViewCell的弱@IBOutlet VAR contentTextLabel:的UILabel!重写FUNC prepareForReuse(){super.prepareForReuse()contentTextLabel.text =零contentTextLabel.textColor =。黑contentTextLabel.attributedText =零}}
最后一类TextTableViewRow:OKTableViewRow  {的init(文本:字符串){super.init(文本,registrationType:TextTableViewRow.defaultNibRegistrationType)}}
扩展{TimeInterval所变种timeText:字符串{让秒= INT(地板(个体))开关秒{壳体0 ... 60:让文本= “\(秒)秒前” 返回truncatePlural(为:文本,时间:秒)壳体60 ... 3599:让分=秒/ 60 let文本= “\(分钟)分钟前” 返回truncatePlural(为:文本,时间:分钟)的情况下3600 ... 86399:让小时=秒/ 3600 let文本= “\(小时)小时前” 返回truncatePlural(为:文本,时间:小时)默认:让天=秒/ 86400 let文本= “\(天)天前” 返回truncatePlural(为:文本,时间:天)}}私人FUNC truncatePlural(对于文本:字符串,时间为:int) - >字符串{如果时间== 1 {返回text.replacingOccurrences(的: “S”,用: “”)}返回文本}}
枚举TextTableViewRowFactory {静态FUNC likesRow(numberOfLikes:UINT) - > TextTableViewRow {让行= TextTableViewRow(文本: “\(numberOfLikes)喜欢”)row.set(命令:.configuration){细胞,串,_在cell.contentTextLabel。字体= .systemFont(ofSize:13,重量:.medium)cell.contentTextLabel.text =串cell.selectionStyle = .none}返回行}静态FUNC captionRow(用户:字符串,标题:字符串) - > TextTableViewRow {让行=TextTableViewRow(文本:字幕)row.set(命令:.configuration){细胞,标题,_在cell.contentTextLabel.numberOfLines = 0 cell.selectionStyle = .none让mediumAttributes:[NSAttributedStringKey:任何] = [.font:UIFont。systemFont(ofSize:13,重量:.medium),.foregroundColor:UIColor.black]让regularAttributes:[NSAttributedStringKey:任何] = [.font:UIFont.systemFont(ofSize:13),.foregroundColor:UIColor.black]让attributedString= NSMutableAttributedString(字符串:用户,属性:mediumAttributes)attributedString.append(NSMutableAttributedString(字符串: “\(标题)”,属性:regularAttributes))cell.contentTextLabel.attributedText = attributedString}回行}静态FUNC commentRow(commentCount:UINT) - > TextTableViewRow {让行= TextTableViewRow(文字:“查看所有\(commentCount)评论“)row.set(命令:.configuration){细胞,串,_在cell.contentTextLabel.font = .systemFont(ofSize:13)cell.contentTextLabel.text =串cell.contentTextLabel.textColor = .graycell.selectionStyle = .none}返回行}静态FUNC timeRow(numberOfSeconds:TimeInterval所) - > TextTableViewRow {让行= TextTableViewRow(文本:numberOfSeconds.timeText)row.set(命令:.configuration){细胞,串,_在细胞.contentTextLabel.font = .systemFont(ofSize:10)cell.contentTextLabel.text =串cell.contentTextLabel.textColor = .gray cell.selectionStyle = .none}返回行}}

陪我们TextTableViewRow,我们创建了一个TextTableViewRowFactory定义四个单独的静态函数来创建我们的每一个文本行。如果我们考虑到上重用重置细胞的特性,在TextTableViewCell将是足够的,以显示所有的不同的文本的配置。

全部放在一起:

到现在为止,我们已经创建的模型,头OKTableViewSectionComponent和所有的不同OKTableViewRowŝ我们需要建立我们的后段。要创建一个部分,我们必须使用以下类型:

类OKTableViewSection

OKTableViewSection可以用被初始化[OKAnyTableViewRow]和/或一个OKTableViewSectionComponentDisplayOption

OKTableViewSectionComponentDisplayOption是枚举将表示该补充视图的OKTableViewSection应显示。对于我们的后部分,我们仅想用显示页眉我们先前定义PostTableViewSectionHeaderViewComponent

最后一类PostTableViewSection:OKTableViewSection {的init(用户:用户,行:[OKAnyTableViewRow] = []){super.init(行:行,componentDisplayOption:.header(组分:PostTableViewSectionHeaderViewComponent(用户:用户)))}}

现在,我们定义了PostTableViewSection,让我们创建一个工厂,以更轻松地创建出柱段!

枚举PostTableViewSectionFactory {静态FUNC部(用于后张贴,宽度:CGFloat的) - > PostTableViewSection {让行:[OKAnyTableViewRow] = [ImageTableViewRow(图像:post.content,宽度:宽度),ActionButtonsTableViewRow(),TextTableViewRowFactory.likesRow(numberOfLikes:post.numberOfLikes), TextTableViewRowFactory.captionRow(user: post.user.username, caption: post.caption), TextTableViewRowFactory.commentRow(commentCount: post.numberOfComments), TextTableViewRowFactory.timeRow(numberOfSeconds: post.timePosted)] return PostTableViewSection(user: post.user, rows: rows) } }

截屏,2018年5月21日,在-12.48.05-PM

这里是你可以用它来创建你的帖子熊的形象。随时让你的帖子的东西,你想!

熊

最后一类ContentFeedViewController:UIViewController的{@IBOutlet私人弱VAR的tableView:UITableView的!私人联络让利= OKTableViewLiaison()私人FUNC部分(为岗位:邮政) - > PostTableViewSection {回报PostTableViewSectionFactory.section(为:岗位,宽度:tableView.frame.width)}覆盖FUNC viewDidAppear(_动画:BOOL){超。viewDidAppear(动画)让交=邮政(用户:用户(用户名: “迪伦”,化身:#imageLiteral(资源名称: “迪伦”)),含量:#imageLiteral(资源名称: “熊”),numberOfLikes:64,字幕:“熊家族熊科的carnivoran哺乳动物,它们被列为caniforms,或狗一样carnivorans。虽然只有八种熊是现存的,他们是普遍的,出现在各种各样的栖息地在整个北半球和部分南半球。“,numberOfComments:25,timePosted:1644)让bearPostSection =部(为:交)liaison.liaise(的tableView:的tableView)liaison.append(截面:bearPostSection)}}

瞧!如果你建立并运行你的项目,你会看到一个帖子片段中显示我们的熊后一个UITableView。的面包和奶油OKTableViewLiaison内谎言进行联络功能。通过联络事宜一UITableView的OKTableViewLiaison中,联络需要控制作为这两个的tableView小号UITableViewDataSource和的UITableViewDelegate。不仅将所有的UITableViewHeaderFooterView的UITableViewCells的的UITableView的注册,您现在就可以开始使用各种OKTableViewLiaison功能操纵UITableView的,在这个例子中,我们只是简单地追加一个新的部分,我们的UITableView的

随意帖子添加到您的UITableView的或者可能引入一个完全新的单元/行类型来显示不同类型的内容。该灵活性OKTableViewLiaison提供了品牌建设的各种UI与UITableView的轻而易举!

OKTableViewLiaison还自带装备有一个简单的API与处理您的所有需求分页OKTableViewLiaisonPaginationDelegate。对于深入版本本教程中,检查出的示例项目发现GitHub上,随着源代码。

如果您发现本文所有有趣/有用的,请给框架上的明星GitHub上