注意:我们发布了这一框架GitHub.

UITATYVIEW.在开发IOS应用程序时,Defacto工具是否有助于我们在开发IOS应用程序时创建一行单元格。典型配置包括一个nsobject.(s)符合UITATIVEVIEWDATASOURCE.UITATionViewDelegate协议,实现所需方法的样板,然后注册必要的UITATiveViewHeaderFooterView.UITATWVIEWCELL.类型与UITATYVIEW.

这种配置就足够了,特别是当你的时候UITATYVIEW.只包含单个单元格类型,但如果我们想处理更复杂的配置,会发生什么?如果我们的话是怎么办什么UITATYVIEW.是由10个以上的单元格类型组成,自定义部分标题/页脚视图,各种操作和高度?确定如何在DataSource /委托方法的实现中处理如何处理的逻辑将很快失控。

在Okcupid应用程188bet金宝搏官网序中,我们不断面临这些情况。这是一个可能会找到的典型实现的一个例子UITATIVEVIEWDATASOURCE.sFunc TableView(_ tableView:UITableView,CellForrowatIdextPath:IndexPath) - > UITableViewCell

Class AdvertisementCell:UigitiveViewCell {}类匹配:UITableViewCell {}类QuestionCell:UigitiveViewCell {}协议模型{} STRUCT广告:Model {} Struct匹配:型号{}结构问题:{} Func TableView(_ tableView:UITableView,CellForrowateDivePath:IndexPath) - > UITableViewCell {让Model = Models [IndexPath.Item]如果让广告= Model as?如果让匹配=型号,则广告{// dequeue,配置和返回广告频率}如果让问题= model astha,则匹配{// dequeue,配置和返回matchcell}问题{// dequeue,配置和返回questioncell}}

随着我们继续添加更多型号类型,它们相应地显示UITATWVIEWCELL.S,我们的代码线性增长。每种情况都有自己的单独的出区和配置逻辑。这种模式可以使我们的代码非常困难地推理和更难维护我们介绍的型号/细胞类型。

通过简单地定义DataSource /委托方法中的逻辑来实现UigitiveViewDataSource / UigitiveViewDelegate在我的意见中对于多单元/型号类型配置不足。考虑到这一点,我开始创建一个帮助我实现的抽象UITATYVIEW.■以更简单的方式。

介绍OktableViewLiaison.!!OktableViewLiaison.是一个框架,它摘要消除所有传统的UITATIVEVIEWDATASOURCE.UITATionViewDelegateBoilerplate,让您使用干净,模块化和可扩展的API,为您建立您的UITATYVIEW.s。

该框架围绕与单个对象进行交互,OktableViewLiaison.,在引擎盖下符合UITATIVEVIEWDATASOURCE.UITATionViewDelegate协议,并处理插入,删除和移动行和移动UITATYVIEW.

说明力量OktableViewLiaison.,我将逐步逐步向您展示如何构建Instagram / Reddit,如内容源,只需使用aUITATYVIEW.UITATiveViewHeaderFooterView.UITATWVIEWCELL.S和这一点OktableViewLiaison.框架。

让我们开始创建一个新的单视图应用程序项目使用迅速Xcode.。包含的最简单方法OktableViewLiaison.进入你的项目是通过Cocoapods.

Pod'OktableViewLiaison'

迦太基支持即将推出。

我们的Feed将显示一系列帖子,每个帖子组成,每个标题表示谁创建它,一个内容以图像的形式,一组动作按钮和文本陈述了图像的标题,总金额评论并喜欢收到的帖子,并创建了帖子时的时间戳。

筛选-2018-05-17-at-11.51.21-AM

我们可以通过创建以下结构来模拟我们的帖子:

struct用户{让用户名:字符串让avatar:uiimage}
struct post {让用户:用户让内容:uiimage let numberoflikes:uint let标题:string let numberofamments:uint let时间戳:timeInterval}

为确保UI的最大可重用性和灵活性,让我们代表一个帖子UITATYVIEW.部分,每个组件都是一个UITATIONHEADERFOOTERVIEW.或者UITATWVIEWCELL.。这样,而不是将帖子建立为一个巨人UITATWVIEWCELL.,我们可以重新排序,删除和添加组件作为产品要求更改。

我们的帖子部分将有一个自定义标题视图,PostTableViewSealderview,即用于包含UIImageView和UILabel以显示用户头像和用户名。

筛选-2018-05-17-at-11.50.12-AM

筛选-2018-05-17-at-11.57.1​​3-AM

最终类PosttableViewsectionHeaderview:UITableViewHeaderFooterView {@iboutlet弱var imageview:uiimageview!@iboutlet弱var titlelabel:Uilabel!override func awakefromnib(){super.awakefromnib()overeview.layer.maskstobounds = true imageview.contentmode = .caleaspectfit} override func layoutsubviews(){super.layoutsubviews()oplyview.layer.cornerradius = imageview.frame.height / 2}}

OktableViewLiaison.表示使用的补充报头/页脚视图Class OktableViewSectionComponent 类型。

OktableViewSectionComponent.使用两个通用类型:

查看:UigityViewHeaderFooterView.是类型的类型UITATiveViewHeaderFooterView.用于视图。
模型是一种用于帮助配置视图的类型。

既然我们有自定义部分标题,才能创建组件作为子类OktableViewSectionComponent.

最终类PostTableViewSectionHeaderviewComponent:OKTableViewSectionComponent  {Public Init(User:User){Super.Init(UsermentType:PostTableViewSeateHeaderviewerviewComponent.DefaultNibregistrationType)设置(高度:.height,70)Set(命令:.configuration){View,view.imageView.Image = User.avatar View.imageView.Layer.BorderColor = Uicolor.Gray.CgColor View.ImageView.layer.bordwintth = 1 view.titlelabel.text = user.username视图.titlelabel.font =.Systemfont(OFSIZE:13,重量:.medium)View.titlelabel.textcolor = .black}}}

我们首先将PostTableViewSectionHeaderviewComponent作为一个子类OKTableViewSectionComponent

然后,我们继续定义我们的初始化器,该初始化器将用户实例作为参数。在我们的初始化程序中,我们拨打电话超级我们还在哪里进入OktableViewRegistrationType.

OktableViewRegistrationType.是一个枚举,表示如何OktableViewLiaison.应该注册A.UITATWVIEWCELL.或者UITATiveViewHeaderFooterView.键入A.UITATYVIEW.。自从我们创造了PosttableViewsectionHeaderview.用一个XIB., 然后XIB.姓名与其相关类相同,我们可以简单地通过.defaultNibregistrationType.作为OktableViewRegistrationType.

最后,我们设置了标题的高度并定义其。配置关闭。OktableViewSectionComponentCommand.代表我们标题/页脚视图的生命周期事件。我们定义的命令闭合通过我们的实例看法, 这模型对象,以及该部分的索引UITATYVIEW.。这。配置每次UITableView Deques部分补充视图,将调用闭包。

现在是PosttableViewsectionealieWerviewComponent.已被定义,让我们开始为我们的帖子建造行。使用使用行OktableViewLiaison.,我们使用以下类型:

class oktableviewrow

如同OktableViewSectionComponent.OktableViewrow.使用两个通用类型:

CELL:UITATWVIEWCEL.是用于行的UITableViewCell类型。
模型是一种用于帮助为行配置单元格的类型。

本节中呈现的第一行是用于内容图像。在这里,我们将创建一个和UITableViewCell,其中包含单个UIImageView固定到其边缘。

筛选-2018-05-17-at-1.18.23-pm

屏幕截图-2018-05-17-at-1.21.51-pm

最终类ImageetableViewCell:UITableViewCell {@iboutlet弱var contentimageView:UIImageView!}
最终类ImageetableViewRow:OKTableViewRow  {init(图片:uiimage,宽度:cgfloat){super.init((图像,宽度),reduciontype:imageetableviewrow.defaultNibregistrationType)Set(高度:.height){模型 - > CGFloat在Let(Image,Width)= Model very = Image.size.width / image.size.height返回宽/ rice.size(命令:.configuration){cell,model,indexpath在cell.contentImageView中。图像= model.0 cell.contentImageView.contentMode = .scaleAspectFill}}}

我们定制的班级声明OktableViewrow.与我们非常相似OktableViewSectionComponent.

我们定义了一个初始化器,它需要两个参数,UIImage和表示宽度的CGFloatUITATYVIEW.(更多关于宽度的宽度)。

而不是通过静态值来确定我们的单元格的高度,而是使用闭合来计算高度。这里的目标是保持每个内容图像的正确宽高比。通过通过我们的UITableView的宽度,我们可以得出正确的高度。

最后,我们通过设置来配置我们的单元格。配置关闭。关闭通过一个实例细胞, 它的模型对象,和索引路径行。

超过15种不同OktableViewRowCommand.您可以为包括封闭封闭的事件瞧瞧删除插入移动重新加载

接下来,我们将使用Emojis实现一个虚拟动作按钮行以显示,评论,分享和书签功能!

筛选-2018-05-17-at-4.50.04-pm

屏幕拍摄-2018-05-17-at-4.47.52-pm

最终类actionButtonStableViewCell:UITableViewCell {@iboutlet弱var licenbutton:uibutton!@iboutlet弱var commentbutton:uibutton!@iboutlet弱var messagebutton:uibutton!@iboutlet弱var书签utton:uibutton!}
最终类actionButtonStableViewRow:OKTableViewRow  {init(){super.init((),starmentType:actionButtonStableViewRow.defaultNibregistrationType)设置(高度:.height,30)Set(命令:.configuration){cell,_,_在cell.likebutton.settitle(“❤️”,for:.normal)cell.commentbutton.settitle(“”,for:.normal)cell.messagebutton.settele(“”,for:.normal)cell.bookmarkButton.settitle(“”,用于:.normal)cell.selectionStyle = .none}}}}

我们帖子的最后一部分是文本。我们可以将文本分解为四个不同的行;喜欢,标题,评论和时间。除了文本颜色,字体和实际文本之外,每行之间唯一的实际差异是它们的高度。以前我们使用静态值设置每行的高度,或用闭包计算它。在这种情况下,我们需要基于其文本的大小来动态的高度。没问题!默认情况下,OktableViewRow将返回高度UITEATVIEWAUTOALDIMINUSIN如果未指定一个,请允许我们设置我们的UITATWVIEWCELL.是自我规模的。我们还可以另外使用估计高度设置oktableviewheighttype.ESTIMATEDHEIGHT.如果需要的话。

筛选-2018-05-17-at-5.50.45-pm

筛选-2018-05-17-at-5.51.18-pm

最终类TextTableViewCell:UigitiveViewCell {@iboutlet弱var contenttextlabel:Uilabel!override func prepasterforreuse(){super.prepareforreuse()contenttextlabel.text = nil contenttextlabel.textcolor = .black contenttextlabel.attributedtext = nil}}
最终类TextTableViewRow:OKTableViewRow  {init(text:string){super.init(text,statchrytype:texttableviewrow.defaultnibregistrationtype)}}
扩展timeInterval {var timeText:String {让秒= int(楼层(self))切换秒{ucase 0 ... 60:let text =“\(秒)秒前”返回truncateprural(for:text,time:秒)案例60 ... 3599:让时间分钟=秒/ 60拍文本=“\(分钟)分钟前”返回truncateprural(for:text,time:分钟)案例3600 ... 86399:让时间=秒/ 3600让文本=“\(小时)小时前”返回truncateplural(for:text,time:hours)默认值:让days = seconds / 86400让文本=“\(天)天前”返回truncateplural(for:text,time:days)私人Func truncateplural(用于文本:字符串,时间:int) - >字符串{如果time == 1 {return text.replacingocurrences(of:“s”,with:“”)} return text}}
enum textitableviewrowfactory {static func likesrow(numberoflikes:uint) - > texttableviewrow {let the = texttableviewrow(text:“\(numberoflikes)likes”)row.set(命令:.configuration){cell,string,_在cell.contenttextlabel中。font = .systemfont(ofsize:13,重量:.medium)cell.contentTextLabel.Text = String Cell.SelectionStyle = .NONE}返回行}静态Func CaptionRow(User:String,标题:字符串) - > TextTableViewrow {LET行=TextTableViewrow(text:caption)row.set(命令:.configuration){cell,标题,_在cell.contenttextlabel.numberoflines = 0 cell.selectionstyle = .none let viewartributes:[nsattribunedstringkey:aft] = [.font:uifont。Systemfont(Ofsize:13,重量:.medium),.foregroundColor:Uicolor.Black]让RementryAttributes:Any] = [.font:Uifont.Systemfont(uifont.Systemfont(Ofsize:13),.foregroundColor:Uicolor.Black] Let AdvancedString= nsmutableattributeString(String:用户,属性:mediumAttributes)属性串.Append(nsmutableattributeString(字符串:“\(标题)”,属性:正规状态))Cell.ContentTextLabel.AttributedText = AttributedString}返回行}静态Func Commentrow(ComminyCount:UINT) - > TextTableViewRow {Let Row = TextTableViewrow(文本:“查看全部\(commentcout)注释“)Row.Set(命令:.configuration){cell,string,_在cell.contenttextlabel.font = .systemfont(ofsize:13)cell.contenttextlabel.text = string cell.contenttextlabel.textcolor = .grayCell.SelectionStyle = .none}返回行}静态Func Timerow(numberofseconds:timeIterval) - > textitableViewrow {let the = texttableviewrow(textofseconds.timetext)row.set(命令:.configuration){cell,string,_在单元格中.contenttextlabel.font = .systemfont(ofsize:10)cell.contenttextlabel.text = string cell.contenttextlabel.textcolor = .gray cell.selectionstyle = .none} return}}}

陪我们TextTableViewRow.,我们创造一个TextTableViewRowFactory.这定义了四个单独的静态函数来创建我们的每个文本行。如果我们考虑重置重复使用的细胞属性,则TextTableViewCell.将足以显示所有不同的文本配置。

把它整合在一起:

到目前为止,我们创建了模型,标题OktableViewSectionComponent.,以及所有不同的OktableViewrow.我们需要创建我们的帖子部分。要创建部分,我们必须使用以下类型:

Class OktableViewsection.

OktableViewsection.可以用一个初始化[okanytableviewrow]和/或一个OKTableViewSectionComponentDisplayOption.

OKTableViewSectionComponentDisplayOption.是一个表示哪个补充视图a的枚举OktableViewsection.应该显示。对于我们的帖子部分,我们只想使用先前定义的显示标题PosttableViewsectionealieWerviewComponent.

最终类PostTableViewsection:OKTableViewSection {init(用户:用户,行:[OkanyTableViewrow] = []){super.init(行:行:行,componentDisplayOption:.header(组件:posttableViewsectionHeaderviewComponent(User:User)))}}}}}

现在我们定义了我们的posttableViewsection.,让我们创建一个工厂以更轻松地创建帖子部分!

Enum posttableViewsectionFactory {静态Func部分(帖子:帖子,宽度:cgfloat) - > posttableViewsection {假设:[OkanyTableViewrow] = [ImageetableViewrow] = [ImageTableViewRow(图片:Post.Content,Width:Width:Width:Width:Width:Width:Width:Width:Widefactory.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-05-21-at-12.48.05-PM

这是您可以用来创建帖子的熊的图像。随意让你的帖子有关你想要的任何事情!

熊

最终类ContentFeedViewController:UIViewController {@iboutlet私有弱var tableview:puityview!Private Let Liaison = OktableViewLiaison()私人Func部分(帖子:POST) - > PostTableViewsection {返回PosttableViewFactory.story.section(for:post,winte:tableview.frame.width)}覆盖Func ViewDideapear(_动画:BOOL){超级。ViewDideapear(Animated)Let Post = Post = Post(用户:用户(用户名:“Dylan”,Avatar:#imageliteral(ResourceName:“Dylan),内容:#imageliteral(ResourceName:”Bear“),Numberoflikes:64,标题:“熊是荨麻疹的狂欢哺乳动物。他们被归类为大甘蓝,或狗般的肉食族。虽然只有八种熊都濒临突出,但它们是普遍的,出现在整个北半球各种各样的栖息地,部分在南半球。。“,NumberOf:25,时间戳:1644)让BearPostsection =部分(for:post)liaison.liaise(tableview:tableview)liaison.append(部分:bearpostsection)}}

瞧!如果您构建并运行您的项目,您将看到一个UITableView,其中一个帖子部分显示我们的熊柱。面包和黄油OktableViewLiaison.谎言内在慰问功能。通过联络A.UITATYVIEW.与之OktableViewLiaison., 这联络控制和既有控制tableview.S UITEVEVIVEDDATASOURCE和UITIONVIEWdelegate。不仅全部UITATiveViewHeaderFooterView.UITATWVIEWCELL.s在UITableView中注册,您现在可以使用各种OKTableViewLiaison函数开始操作UITableView,在此示例中,我们只是将新部分附加到我们的新部分UITATYVIEW.

随意添加更多帖子UITATYVIEW.,或也许介绍一个完全新的部分/行类型以显示不同类型的内容。灵活性OktableViewLiaison.提供建立您的各种UIUITATYVIEW.微风!

OktableViewLiaison还可以使用简单的API处理您的所有分页需求OktableViewLiaisonPagomationDelegate.。有关本教程的深入版本,请查看找到的示例项目GitHub.以及源代码一起。

如果您在所有有趣/有用的文章中发现了这篇文章,请给框架一个明星GitHub.