Tag: uitableview

编写一次-在整个项目中随处使用,无条件-无修改

视力: 更少的代码,更少的错误,更少的测试用例 任务: 通过在极端情况下减少每种情况下的项目代码,减少错误的可能性并提高可伸缩性。 挑战是什么? 您是否曾经考虑过为整个项目只编​​写一次表视图委托和数据源? 一旦您完成了在一个位置编写代码的工作,即实现数据源和创建表视图的委托方法,就不需要在整个项目中实现数据源和表视图的委托的视图控制器,就必须在一个位置编写仅放置一次并使用很多次,当您将使用不同的单元设计开发新的屏幕时,不需要任何条件或修改。 您的可重用代码也必须可在其他项目中使用,而无需任何修改或条件。 您的解决方案必须是框架级别的解决方案,而不是项目级别的解决方案。 您无需在此处创建框架,但我的上下文是,您不能限制用户使用他/她自己的现有基类(如果他/她已经在项目中),例如UIViewController和UITabelViewCell的基类。 您不得限制用户访问Apple的UIKit提供的API来创建表视图或表视图单元格,应允许用户使用纯代码或XIB或情节提要创建表视图或单元格。 用户-正在使用您的可重用组件的用户 在常规编码中,每当在视图控制器中确认UITableViewDatasource时,编译器都会要求您提供两个必需的方法cellForRowAtIndexPath: 和 numberOfRowsInSection: 如果您错过了这两种方法中的任何一种,则会出现编译时错误。 您的可重用组件必须允许用户在需要时无限制地在view controller手动编写委托和数据源方法。 这意味着如果用户只想编写cellForRowAtIndexPath: 具有自定义逻辑且未实现numberOfRowsInSection:如果用户想要在cellForRowAtIndexPath:自定义逻辑,则该方法必须起作用cellForRowAtIndexPath: 只要。 同样,所有UITableViewDelegate方法也是如此。 不允许使用闭包或块或obj-c运行时 , 它只能通过委托模式来实现。 开始考虑挑战。 如何参加这项挑战? 推动自我,学习新事物并成为赢家。 1.只需填写此Google表单: https : //goo.gl/forms/zj2YrQu3H1LTbEKw2 2.为您的解决方案提供适当的步骤或Readme.md,因此我可以通过创建新的视图控制器,新的单元格和新的数据模型或字典来测试您的组件,从而对其进行测试。 3.解决方案提交: https : //goo.gl/forms/RIgCO1EAqmHgPGPN2 优胜者的奖金是多少? 获奖者将获得151.00 USD的奖金。 可能会增加到200.00 USD或更多,具体取决于参与者和获胜者的总数。 如果将有不止一名获奖者,我将按获奖者人数分配奖金。 如果有两名获胜者,则奖金为151.00美元 ,则每位获胜者将为151/2美元或更多 。 获奖者将如何获得奖金? 贝宝 UPI付款 Paytm | 免费|电话支付| G Pay(Google pay)应用 […]

快速了解UITableViewCell可重用性

总览 表格视图在单个列中显示项目列表。 UITableView是UIScrollView的子类,尽管UITableView仅允许垂直滚动,但它允许用户滚动表。 组成表格中各个项目的单元格是UITableViewCell对象; UITableView使用这些对象绘制表的可见行。 Tableview不会在每次调用行单元格时都初始化单元格,它会重用 em。 明显!! every‍♂️每个人都知道,但问题是“ 如何?” ”。 诸如TableView之类的Apple API使用称为“ 对象池 ”的东西来进行管理。 对象池 对象池是一种设计模式,它可以重复使用🔄一组预初始化的对象,或者可以说它维护了实际需要的对象池,然后又一次又一次地重复使用它。 Tableview充当池的客户端,当它请求对象时,池将从池中返回一个实际项目,该项目可重复使用,而不是每次都初始化一个新对象。 当客户端完成对象处理后,该对象将返回到池中以供重用。 对象池用于提高性能,因为没有创建或销毁对象,而是将它们从池中抽出并在使用后返回给对象,从而节省了更多时间和内存复杂性。 在TableView的情况下很容易理解。 创建单元时,它是从池中提取的,在完成其工作时,或者万一可以说,在TableView中完成显示将返回到池中。 对象池的实现: 让我们尝试为自己创建对象池。 让我们创建一个可用于约束通用池项的协议。 协议可重复使用{ 函数重用() } 我们可以在协议中添加重用函数,在该协议中,当元素从池中重用时,我们可以重置视图以重用它,并重设视图(​​reuse)。 类ResuableCell:UITableViewCell,可重用{ 函数重用(){…} } 现在我们可以建立对象池了。 Pool { 私有let maxElement:Int 私人让生产者:()-> T public init(maxElementCount:Int,producer:@escaping()-> T){ 自我生产者=工厂 self.maxElement = maxElementCount } } maxElement是我们要在池中进行初始化的元素的最大数量,就像我们在TableView中具有numberOfRows或numberOfSections一样。 生产者函数需要告诉我们如何制作通用元素 我们需要再添加两个绘制和释放功能,例如在TableView中,该单元格在屏幕上显示后将被释放。 Pool { 私有let maxElement:Int […]

在Interface Builder中将UITableViewController转换为UIviewCntroller

当我需要在表视图之外添加视图时,通常必须将Interface Builder中的UITableViewController更改为UIViewController 。 那么,我们如何实现这一目标? 🤔 将UIViewController从Objects库拖到 IB并从UITableViewController获取表视图并设置合适的约束,不要忘记从IB中删除UITableViewController 打开您的情节提要作为源代码,并搜索有关tableview控制器的信息, 您将发现如下所示 : 因此,将<tableViewController更改为<viewController ,并将结束符 更改为 。 所以会像这样 作为Interface Builder打开情节提要,它将如下所示 但是我们需要将表视图嵌入容器视图🤔中,因此我们需要再次打开情节提要作为源代码并对其进行修改,因此添加视图标记以包含tablview: 我们希望已完成🤗,但是当您打开情节提要并需要在表视图中添加约束时,会得到此🤦‍♂️ 因此,要使约束可用,您需要从标签下面的标签中删除<autoresizingMask key =” autoresizingMask” widthSizable =” YES” heightSizable =“ YES” / >标签 ,然后将adtranslatesAutoresizingMaskIntoConstraints =“ NO”属性添加到标签,因此它看起来像这样 现在您可以向表视图添加约束view 您可能会看到这种方法有些困难,但是尝试使用它,我相信您会发现它很容易而且值得拥有,并且当表视图如此复杂时,我相信这将是一个很好的选择。 希望这对您将来的项目有所帮助Thanks,谢谢

如何在UITableView中删除多余的分隔线

当您的UITableView没有足够的数据来填充屏幕的长度时,它将显示带有分隔符的空单元格来填充屏幕。 我遇到了几种不需要多余的分隔线的情况。 如果您自己遇到过这种情况,那么这是摆脱它们的简单技巧,不需要任何代码。 UITableView具有两种不同的模式。 一个用于静态内容,其中您在Xcode的Interface Builder中手动添加每个单元格,另一个用于在代码中动态构建内容。 仅当使用动态内容时,才会出现带有分隔符的多余的空单元格。 将普通的UIView添加到UITableView的页脚 为了摆脱空单元格,我们要做的就是在UITableView的页脚中添加一个空的UIView。 UITableview有两个插入点,可在单元原型的上方和下方添加页眉和页脚视图。 首先,从对象浏览器中获取一个普通的UIView,并将其拖动到所有单元原型下方的页脚位置。 有效! 分隔线不见了。 自定义颜色可能需要其他工作 如果您的UITableView使用默认的背景色,那么您不必做任何其他工作。 但是,如果您为UITableView使用自定义背景色,或者希望页脚与单元格的颜色匹配,请更改页脚视图的背景色以进行匹配。 如果UITableView中没有数据,则可能还必须拖动页脚视图的大小以使其足以覆盖屏幕。 我希望您发现此解决方案有用。 如果您知道在不添加自定义代码的情况下完成同一件事的更简单方法,请在下面留下评论。

管理多个单元

斯威夫特3.0 在iOS中,通常在tableView中使用不同类的多个单元格。 由于我们的cellForRowAtIndexPath可能很快变得肿,所以这可能会变得很毛茸茸。 我已经看到开发人员直接使用indexpath确定要出队的单元。 对单元格的索引路径进行硬编码不仅使代码更难阅读,而且也使更改变得更加困难。 我发现的解决方案是使用cellList来管理所有这些。 将单元格限制为枚举 第一步是创建一个枚举,其中包含表视图可以出队的所有可能的单元格。 假设我们的tableView将显示有关使用3个单元格的人的信息。 一个AddressTableViewCell,EmailTableViewCell和PhoneTableViewCell。 然后,我们的枚举将包含三个值,如下所示: 列举PersonTableIndexPath { 案例地址 案例电子邮件 手机壳 } 这确保了我们的tableView仅能够使枚举中列出的单元格出队。 如果需要,还可以更新枚举以支持关联的值,但是此示例将保持简单。 使用单元格列表管理单元格 让cellList:[PersonTableIndexPath] = [.Address,.Email,.Phone] 我们的cellList本质上是一个枚举数组。 这样,我们将索引路径隐式链接到单元格类。 唯一的好处就是更改枚举在单元格中的位置List将直接与tableView中显示的索引路径相关。 如果已经正确处理了该cellForRow,则无需更改它。 在Table View的数据源中使用单元格列表 在numberOfRowsInSection中,一个衬线就足够了 返回cellList.count 在cellForRowAtIndexPath中,我们可以如下使用cellList: 让cellType = cellList [indexPath.row] 切换cellType { 案例。地址: 返回setupAddressTableViewCell(indexPath) 案例。电子邮件: 返回setupEmailTableViewCell(indexPath) 手机。 返回setupPhoneTableViewCell(indexPath) } 我们的设置方法将负责使单元出队,设置和返回。 由于开发人员确切知道单元格设置代码的位置,因此这使代码非常干净。 而且,cellList的魔力还没有结束。 如果我们将cellList更改为可变的,则可以在运行时更改枚举的顺序🙂 在运行时更新单元列表 如果我们需要添加另一个手机单元,我们要做的就是更新单元列表。 cellList.append(.Phone) tableView.reloadData() am! 真的是这样。 […]

Swift中的回调– TableView和CollectionView的实际示例

您非常喜欢某件东西,因此您始终希望围绕它。 所有程序员都沉迷于某种东西,如果您是iOS开发者,那么当您被介绍到UITableView和/或UICollectionView ,您将UICollectionView 。 当您使用UIScrollView危险时,您会更加爱他们(我是说😢)。 我已经看到程序员非常喜欢某些数据结构(即enum , struct ),以至于他们只能思考。 这种爱带来了一些在别的事情的帮助下做某事的非常酷的技巧。 因此,在开始快速讨论之前,让我更新前面提到的报价, 您非常喜欢UITableView和/或UICollectionView ,以至于即使是简单的输入FORM看起来也UICollectionView 。 请参阅此非常简单的表单以获取用户输入。 它具有一些文本字段和一些标题标签。 可以使用UIScrollView在本地UIViewController轻松设计和维护(适用于较小的屏幕)。 但是,如果您喜欢TableView,那么您会发现它也可以很容易地实现。 我认为它具有一些明显的优势 。 但是让我们看看这怎么可能是一个实施问题。 表单的设计和表示形式与自定义单元格类完全没有问题,但是问题是如何将数据从custom cell对象传输到TableViewController对象。 我将通过图表显示。 现在,可以通过多种方式将输入文本返回给Parent ViewController 。 我们可以使用protocol声明, Notification userInfo等来实现。但是今天,我将讨论一种通过回调函数完成此操作的巧妙方法。 现在,在各种平台和语言中以各种方式定义了回调。 简单地说,回调会将某些内容返回给调用方。 它可以返回值,引用,函数或返回自身。 好的好的。 我说话太多了。 让我们看一些代码。 假设这是一个自定义UITableViewCell类 由名为UserController的UITableViewController实例化。 我们可以在控制器中UITableViewDataSource cellForRowAtIndexPath方法中执行此操作。 让cell = tableView.dequeueReusableCell(withIdentifier:“ singleTfCell”,for:indexPath)为! SingleTfTableViewCell cell.staticLbl.text =“公司” cell.inputTf.text = company ///如果表单处于编辑用户信息模式 返回单元 我们知道。 来吧,已经显示了回调!! 是的,我要去。 […]

TableViewをDRYな设计にリファクタリングした话

“アプリ开発の工数の8割はTableViewに使われている”と言われることもある,アプリUIの花形TableView。荒れがちなTableView周りの设计について,ペイモでのリファクタリング事例を绍介します。 Controllerイモでは,共通のViewController ・ Presenterに分岐を书いてデータや机能に差分にTableViewでも无理やり复数画面で使い回していました。开発初期はこれでもよかったのですが,机能拡张に伴い特に使いしがの界界を迎えたため,今回绍介する设计へリファクタすることとなりました。 同じようなデータを表示するTableViewが复数ある。 各TableViewごとに微妙に机能差分(検索の有无,セル选択时の挙动の违い等)がある。 一つのTableViewに复数种类のデータを表示する(「ユーザ情报」と「お知らせ」など)。 や仮ータの过滤器や仮名のインデックスなど,共通化したいロジックがある。 倾向于として,ペイモではClean Architectureを采用しています。 ViewController→演示者→UseCase→存储库 清洁建筑に则ってAPIコールします。 存储库→UseCase→数据模型 APIの取得结果をドメイン层の责务范囲で整形してDataModelに积み,Presenterに返却します。 数据模型→演示者→ViewController Presenterは,UseCaseから返却されたDataModelからその画面の表示に必要なデータを取得してDataSourceを作成し,ViewControllerに引き渡します。 枚举协议。 ///セル用のデータ种别 通讯协定CellRenderable { //种别判定关数(TableViewのDelegateメソッドでの型判定に使用します) func getType()-> CellDataType } ///种别「A」のセル用データ class CellTypeAData:CellRenderable { func getType()-> CellDataType { //自身のデータ种别を返します 返回.a } //このデータ种别固有のプロパティ群 var hoge:字符串? } ///种别「B」のセル用データ class CellTypeBData:CellRenderable { func getType()-> CellDataType { 返回.b } //このデータ种别固有のプロパティ群 var hoge:字符串? } ///主持人にデータを引き渡すモデル […]

使用一流的对象创建具有多种单元格类型的UITableViews

问题 在AI公司工作时,您总是会做很多技术演示,以在野外使用某种技术。 现代算法往往具有很多您想尝试的参数,有时工作的结果只能由人类认可,尤其是当它与任何类型的图像处理/计算机视觉或AR / ML类型相关时应用程序,您必须用眼睛检查结果。 这通常导致必须创建一堆屏幕上的按钮/滑块,以便可以对核心逻辑进行参数设置,并查看新的超参数如何影响结果。 在进行了几次这样的演示之后,我决定创建一个自定义调试菜单,您可以在其中以声明方式添加几个选项,然后观察更改。 我一天通过分叉现有的调试工具Dotzu制作了原型。 项目仍处于起步阶段,但现在或多或少可以满足我的需求。 您可以在公共仓库中使用它。 以下是取得的成果的小演示: 现在,有趣的部分。 我们创建一个UITableViewController子类,在其故事板上没有单元原型: 所有的魔力都进入了它的实现。 让我们来看看: 在最底部,我们声明要呈现的模型数组 这是最有趣的部分。 由于一流的类型对象不可比,因此我们使用Swift标准库中的 ObjectIdentifier结构为每个Type对象创建Hashable / Equatable代理对象。 我们声明一个字典和两个方便的方法来注册并从中获取类型。 由于它是重复的代码部分,因此可能应将其移至称为TypeRegister或类似名称的单独类中。 3.在viewDidLoad()方法中,我们使用一个小的辅助方法将单元格类型注册到表视图中。 4.接下来,我们将关联的Model-View对注册到我们的类型字典中。 5.在cellForRowAt中:我们从数组中获得一个模型,为其确定一个单元格类型,并出列适当类型的单元格。 6.最后,我们告诉UITableView使用自动布局来计算单元格的高度,因为它可以从一个选项到另一个选项。 而已! 现在,您有了UITableView的60行代码的超灵活实现,可以处理其中无限数量的模型。 用法 框架的使用非常简单。 您所要做的就是通过调用一种方法来一次初始化调试菜单(通常在AppDelegate中): DebugMenu.sharedManager.enable() 然后以声明的方式声明您的选项(通常在控制器的viewDidLoad中 ): 通话开始的结果可以在故事开始的视频中看到 由于该仓库专用于调试,因此您可能希望使用#if DEBUG…#endif子句覆盖与DebugMenu的所有交互。 最后的话 由于UI工程不是我每天都会做的事情,因此,我很想听听您对这项技术的反馈,并希望听到关于如何做得更好的任何指导。 希望您喜欢阅读! 不要忘了在GitHub上使用仓库,并在Twitter上关注我。

演示控件,自定义视图和更轻巧的UIViewControllers(第1部分)

现在我们有了MVVM,MVP,VIPER,VIP,但是其他部分呢? 复杂的UI逻辑应该放在哪里? 注意:这是系列文章中的第一篇,我将在其中讨论一些通过抽象UI呈现逻辑来使UIViewControllers变薄的方法。 接下来的帖子将在接下来的几天发布。 当我开始开发iOS应用程序时,我开始使用Apple的首选架构模式Model-View-Controller(MVC)。 我们都知道,MVC导致职责分离非常糟糕。 视图控制器充当视图和模型之间的中介者,并以处理许多杂乱的代码(从UI逻辑和导航逻辑到业务逻辑和API调用)为结尾。 如果您注意到了这一点并搜索了替代方法,则可能听说过MVVM,MVP,VIPER或VIP。 如果您还没有听说过这些,我强烈建议您尝试其中的一些方法(https://medium.com/ios-os-x-development/ios-architecture-patterns-ecba4c38de52#.6bew98dms)。 人们认为每种MVC替代方案都可以解决一个特定的问题,各有千秋,但是它们都有一个共同点: 它们将逻辑与表示分离开来 ,从而使UI完全可互换。 那太好了。 现在,UIViewController已被隔离,可以无问题地替换为另一种表示方式。 这真的很酷。 当我开始使用MVVM开发自己的应用程序时,我注意到UIViewController变得更薄了,因为它没有任何业务逻辑,但似乎缺少了一些东西。 表示逻辑仍在使视图控制器超出预期,因此我花了一些时间思考并发现了一些解决方案。 今天,我将解释其中的第一个:与视图控制器分离的UITableView协议。 孤立的表格视图 我想从视图控制器中获得的第一件事是UITableViewDataSource和UICollectionViewDataSource。 有些人已经讨论过如何在视图控制器之外获取数据源。 这个想法很简单。 当视图控制器中有UITableViewDelegate和UITableViewDataSource时,我们必须考虑索引,单元格高度,单元格标识符以及许多我们真正不关心的低层概念。 更好的方法是在方程中添加新的分量。 可以将其命名为“表视图”驱动程序,并管理表视图的显示详细信息。 计划 我们将引入一个新组件,该组件将成为UITableView的委托和数据源,并将抽象化视图控制器的细节。 表格视图驱动程序代码 这里有一些注意事项: 表格视图驱动程序存储对其显示的数据的引用。 它还存储对其管理的表视图的引用。 尽管视图控制器不必再担心索引和底层表示的细节,但它可能想了解高层逻辑,例如何时选择项目。 表格视图驱动程序是表格视图的委托和数据源。 最后,它公开了一个高级公共接口,以便视图控制器可以处理它。 简化的视图控制器代码 通过遵循这种方法,视图控制器将不仅更薄,而且更具声明性,并且可以在更高的抽象级别上工作。 让我们看一下简化的视图控制器代码: 有一些重要的注意事项: 我们可以从表视图底层表示逻辑中抽象视图控制器。 但是,视图控制器将继续了解表视图的存在。 这是一个问题,因为我们不能例如在不修改控制器的情况下用UICollectionView替换它。 视图控制器通过强烈引用它来拥有表视图驱动程序。 视图控制器负责实例化表视图驱动程序并将其自身分配为其委托。 视图控制器调用表视图驱动程序的高级方法。 视图控制器是表视图驱动程序的委托。 结论 我们知道,应该通过将视图控制器封装在诸如视图模型或演示者或交互器之类的组件中,将其与业务逻辑隔离开来,但是视图控制器将继续负责底层的表示逻辑。 在本文中,我讨论了一系列方法中的第一个,我们可以使用这些方法将视图控制器拆分为一堆组件,这些组件将只负责演示的一小部分。 第一种方法涉及使用一个对象,该对象处理表视图(或集合视图)表示逻辑,并向表视图公开简化的抽象层接口。 在以下文章中,我将讨论其他方法,例如表示控件和自定义视图(以编程方式以及使用xibs的方式)。 如果您以其他方式执行此操作,我将很高兴听到它。 请在下方留下你的意见! 谢谢!

您是否在写Objective-Swift?

Objective-Swift [名词]:以Objective-C的约定和约束编写的Swift代码 在学习Swift的早期,我可能不知道或根本太害怕使用该语言的强大功能。 我以Objective-C的形式编写了Swift代码,导致不必要的可变性和多余的额外行。 以下是一些我最终不懂得好处的习惯。 出队细胞 客观快速 迅速 避免cell变量 没有可选的cell可以强制展开 行数少 命名空间常数 客观快速 扫一扫 改进了相关常量的可读性 富有表现力的枚举 物镜转换 迅速 没有重复的字符串; 字符串与枚举大小写相同 添加诸如OPTIONS类的另一种方法仅需要添加另一种情况 阵列运算 客观快速 迅速 没有创建其他变量 富有表现力的代码读起来就像一句话; “获取姓名并映射到其大写版本,并为每个姓名打印出来” 类型检查 客观快速 迅速 没有力量解开 结论 从Objective C背景学习Swift可能会导致称为Objective-Swift的代码。 Swift比Objective C具有许多优势,因此,恳请您发现利用这些语言的高级功能的方法。