Tag: Tableviews

面向协议的UITableViewCells

这篇博客文章展示了如何通过使用面向协议的编程 (POP)作为子类化或组合的更好替代方法来实现一组UITableViewCell变体。 准备? 我们走吧! 给我看看细胞! 在构建我的Cast Player应用程序时,我需要添加几个设置页面,以允许用户在应用程序中进行一些调整,并包括指向“发送​​反馈”表单和一些“关于”屏幕的链接。 这是最终结果: 从上面的屏幕中,我们可以识别六种不同类型的单元格: 总体而言,这些细胞具有以下特征(或行为): 单元格突出显示 显示标题 显示人类可读的字节数 我们如何去建立一组能很好地代表这六个细胞变异的类呢? 第一步是列出网格中的所有单元格类型和所需特征: 从上表可以看出: 所有细胞都没有采用这些特性。 一些特征是某些细胞所必需的,而其他细胞则不需要。 这意味着构建UITableViewCell类层次结构在这里无法正常工作。 实际上,这些单元格类型都不是基础类的理想选择。 该怎么办? 🤔 协议和扩展! 好极了! 幸运的是,这篇关于Swift 2.0中Mixins和Traits的精彩文章可以为我们指明正确的方向。 直观地讲,协议和扩展对于该用例确实可以很好地工作,但是如何在此处正确使用它们呢? 这个想法是我们可以使用协议为每个特征定义接口 ,并提供带有扩展的默认实现 。 然后,我们可以创建非常小的UITableViewCell子类,并使它们仅符合所需的协议。 在另一个名为“面向协议的MVVM简介”的精彩演讲中,探讨了一个非常类似的问题。 让我们看看它是如何工作的! 有了协议和扩展,我们可以编写第一个特征TitlePresentable : 在代码中,这表示为: 注意 : HighlightableTableViewCell是通过子类实现的唯一特征,并且可以用作三种其他单元格类型的基类。 一旦为给定类型选择了基类,则只能通过协议扩展来添加其他特征。 结论 使用Swift协议和扩展作为增加行为(特征)的一种方式,可以在我们的类的设计中取得重大胜利,并有助于保持层次结构的平坦。 🚀主要优点: class媚的阶层阶层 生成的API /类可以更轻松地扩展 与添加和删除代码相比,添加和删除协议一致性更容易 减少代码重复 欢迎反馈 这篇文章中介绍的解决方案对我和我的特定用例都非常有效-我希望这个实际示例可以帮助我比起初时更好地理解如何使用协议扩展。 如果您知道这样做的更好方法,请在评论中告诉我! 注意 :这篇文章首次出现 在 2016年6月18日发布的 […]

iOS中具有通用数据模型的自定义可重用数据源。

UITableView和UICollectionView是用于在任何类型的iOS应用程序中呈现数据的两个常见UI组件。但是将这些大数据呈现到单元中并不是什么大问题,主要的问题是我们如何处理这些数据。 让我们以UITableView为例,通常通过在viewController中采用UITableviewDatasource协议一致性,我们可以使用它的一些专用方法来处理tableview内部的数据呈现。 这是简单的代码片段示例 上面的例子非常简单,我们只是为viewController创建了一个扩展,并添加了所有tableview数据源方法。 它是如此的好和简单,但是为什么我应该使用Custom数据源呢? 好的 !!!! 当必须在其他视图控制器中显示这些相同的数据块时,您将怎么办。 没什么大不了的,我也将在其他视图控制器中创建相同的东西。 创建自定义可重用数据源可以处理整个应用程序中的所有数据源逻辑和数据模型渲染部分。我在整个应用程序中都说了。是的,但是不同控制器的数据模型不同,所以我将自定义数据源设置为一个通用模型类型,因此只需使用您的数据模型实例化此自定义数据源,以下是代码段。 在这里,我采用了模型(用于数据模型渲染),reuseIdentifier(用于使TableView单元格标识符出列)和CellConfigurator(它是一个元组,它同时容纳Data模型和UITableviewCell,其工作方式类似于tableview单元格中用于索引处行的闭包)作为参数以上课程。 我还在此类的扩展内部创建了一个静态方法来管理特定的数据模型。您还可以根据需要创建自己的模型。代码段。 扩展TableViewCustomDataSource,其中模型== ItemsDetailsLists {静态函数displayData(用于itemLists:[ItemsDetailsLists],withCellidentifier复用标识符:字符串)-> TableViewCustomDataSource {返回TableViewCustomDataSource(模型:itemLists,reuseIdentifier:reuseIdentifier,cellConfigurator:{(数据,单元格)入口itemcell: ItemListsTableViewCell =单元格为!ItemListsTableViewCellitemcell.setupParameters(itemlist:data)})}} 在您的viewController内部只需创建一个像这样的属性 私人var dataSource:TableViewCustomDataSource ? 这里的ItemDetailsLists是我的数据模型,一旦获得响应,就可以像这样设置您的customdatsouce属性,并将tableViewdataSouce设置为customdatasource。 func renderTableViewdataSource(_ itemlists:[ItemsDetailsLists]){dataSource = .displayData(用于:itemlists,带有Cellidentifier:“ ItemListsTableViewCell”)self.itemListTableview.dataSource = dataSourceself.itemListTableview.reloadData()} 这是完整的源代码Github链接 欲了解更多博客,请点击此链接 参考文献: *重构视图控制器,作者Paul Hudson Swift中可重用的数据源 通过约翰·桑德尔 Shakti Prakash在about.me 我是印度班加罗尔的软件工程师。 查看我的仓库。 关于我

Pola Arsitektur MVVM pada迅捷

您尝试过MVVM吗? 嗨,😁! Pastikan Anda Sudah Paham Mengenai TableViewController , Extension和 关闭回调 西伯利亚甜菜 苹果merekomendasikan Pola Arsitektur MVC(模型-视图-控制器) 开发者 dalam iOS / MacOS 开发。 Namun dengan adanya ViewController pada Swift,banyak aplikasi yang dibuat menjadi seperti: Dengan ViewController是MVC(Massive View Controller)。 月经MVVM Dengan menggunakan MVVM,维护部门维护Sebuah aplikasi dapat dibangun secara lebih rapi dan mudah untuk di maintenance。 MVVM(Model-View-ViewModel)记录数据和数据数据ViewController和ViewModel。 Dimana ViewController […]

实现UIRefreshControl

前几天我在和朋友聊天,他提到了一些很有趣的事情。 他正在一个项目中,他们根本不使用任何开源代码(即,没有直接依赖项)。 这让我开始思考,如果我在相同的约束下运作,我的项目会是什么样子。 因此,当我最近被要求实施“按需刷新”功能时,我认为我可以在不咨询开源霸主的情况下试一试。 总览 实现可刷新的样式刷新控件,该控件可以附加到UITableView上,而不会泄漏太多实现细节。 需要使用可响应状态更改的文本和图像进行自定义。 源代码可以在这里找到。 由于很快就把它放在一起,所以还没有经过充分的测试,但是似乎可以正常工作。 如果您有任何改进方法,请告诉我。 第一站,UIRefreshControl 我在这里写了很长的篇幅谈论股票更新控制,但是我看到了它们的利弊时选择了: +易于使用,可直接放入解决方案 –难以定制 –非全萤幕检视画面上的视觉错误,例如跳动的动画 如果您对股票动画没问题,正在使用全尺寸的表格视图以及使用UITableViewController,那么这将是一个完美的控件。 不幸的是,这些都不适用于我试图做的事情。 在使用UIRefreshControl进行了一些修改之后,我放弃了自己的程序并推出了自己的程序。 我真正喜欢的是Apple的刷新控制界面。 它们仅公开一个动作(UIControlEventValueDidChange)和一组方法(beginRefreshing和endRefreshing)。 这使得管理表视图编码时如何与控件交互以及将所有实现精巧地保留在刷新控件本身中变得非常容易。 因此,我从他们的设计中得到了启发,以启发我自己的版本。 但是在我们开始之前 UIRefreshControl如何工作? UIRefreshControl的核心极其简单,但与其他所有细节一样,魔鬼也是如此。 我无法确切地说出苹果实施的工作原理,但我必须想象流程如下。 要记住的关键是我们将使用tableView子类的scrollView —因此,当我在下面引用tableView时,它实际上是其scrollView超类的属性。 观察tableView内容的偏移量 当contentOffset.y> pullDistance时,触发刷新 调整tableView contentInset和contentOffset以解决以下状态: 默认值(用户完全没有与tableview进行交互) 拉(用户已拖动表格视图,并且控件尚未完全显示) 拉动(用户已拉动表格视图,并且控件已完全显示,但尚未达到刷新距离) 拉动和刷新(用户已拉出足够的距离以达到刷新距离) 已发布(用户在刷新距离之前已释放表) 已发布(用户在刷新距离后已释放表) 我们实际上并不会专门针对所有这些状态进行编程,但是最好记住控件将负责处理哪些状态,并为我们提供如何对这些状态做出反应的良好框架。 另一个有趣的地方是来自Apple的文档:“拥有刷新控件的UITableViewController对象还负责设置该控件的框架矩形。 因此,您不需要直接在视图层次结构中管理刷新控件的大小或位置。”因此,我们将尝试做同样的事情,并使它对于最终视图控制器尽可能地无缝。 自定义刷新控件 设置此控件将是了解滚动视图的contentOffset和contentInset如何工作的问题,然后如上所述适当地调整为不同的状态。 让我们遍历每种状态并了解视图的外观,以便我们对需要做的事情有很好的了解。 内容偏移 苹果将​​其描述为“内容视图的原点与滚动视图的原点之间的偏移量”,这实际上是很有意义的。 contentOffset只是任何滚动视图上的一个属性,它是一个精确描述了此CGPoint的属性。 contentOffset可以告诉我们用户将滚动视图从其原始位置拖动(或偏移)了多远。 该点将从(0,0)开始,并在您向下拖动滚动视图时,偏移量将开始增大(0,-1),(0,-2)。一直到用户拖动的程度。 回想一下,负数表示用户在视图上向下拖动。 因此,这样做的目的是提供一种简单的方法来查看滚动视图被拖动到多远,并且一旦有了,我们就可以通过执行类似这样的操作来响应contentOffset.y。 我们使pullDistance保持正值,以便以后使用时更容易。 -(void)scrollViewDidScroll:(UIScrollView *)scrollView […]

UITableViewController将自动调整内容相对于键盘的位置(iOS,Swift)

我如何遇到这个话题 我过去很少使用UITableViewController。 我创建的视图很少是简单的tableViews。 相反,它们包含自定义的页眉,页脚,弹出窗口,按条件排列的按钮等。插入了全尺寸tableview的UITableViewController不符合要求。 添加一个tableview并为UIViewController设置一些委托就足够了。 我不明白的 那么,什么时候应该使用UITableViewController? 我现在如何理解 UITableViewController具有一个有用的特性: 在tableview中选择输入字段(例如textView,textField)时,它将自动调整滚动插入,以便在键盘上方可以看到输入。 我做了什么 这是一个简单的项目: 运行该项目,结果是这样的(对拉伸效果差的gif表示歉意): 那样可爱吗? UIViewController的实现需要 键盘高度 当前位置 响应者职位 从上面计算滚动插图 设置插图 所有这些都由UITableViewController隐式处理。 当然,这可以通过使用默认实现定义键盘帮助程序协议来实现,但是如果这看起来太麻烦了,那么查看ContainerViewController + UITableViewController可能会很方便。

使用GCD从本地/服务器加载数据并在Tableview中显示

要从本地/服务器文件加载数据,应具备swift知识,iOS App开发,View-controller和tableview的知识。这篇文章将分为两部分,第一部分我们在本地获取数据,第二部分将从服务器获取数据。逐步指导 我们将首先设置项目,只有一个视图控制器包含一个表视图,我们还将创建一个名为DataLoader的单独服务,该服务将从本地文件或服务器获取数据,为简化起见,全班将遵循单例模式 2.在ViewController.swift中,我们将设置IBOutlets,并将其设置为tableview的数据源。 在viewWillApper中,我们调用getNames函数,该函数将依次调用DataLoader服务函数getNamesFromServer / getNames,此函数需要一个完成块,因此我们向其传递PopulateTable函数 3. PopulateTable我们检查是否成功请求,如果不是,则输出错误,如果成功,则从收到的响应中设置名称,并在tableview上调用reload 4.将txt文件添加到您的项目中,其中一些名称以json格式显示 5.在DataLoader.swift中,我们创建一个函数getNames 首先,我们获得文件的路径,该文件在本地添加,然后将其转换为URL的实例,并初始化名称数组 6.我们将优先级设置为后台的DispatchQueue.global称为异步后台程序,我们将其称为并发后台队列,因为我们不知道加载数据将花费多少时间,直到那时我们无法停止执行主线程这样做,我们的应用似乎会挂在二手设备上,给用户带来缓慢的用户体验 7.我们将url的内容转换为DATA对象,然后使用JSONSerialization类将其反序列化,然后转换为json对象 8.我们将把这个json对象解析为字典(因为这样做了)并提取名称(在数组中一个接一个地添加它们) 9.我们现在将在Main队列上调用完成处理程序,因为任何UI更改都必须在主队列上进行,否则应用程序将崩溃(或发生意外行为),或者如果上述任何步骤失败,我们将使用调用完成处理程序成功=错误 10.运行应用 5在DataLoader.swift中,我们创建函数getNamesFromServer 我们创建一个URL对象,获得URLSession.shared会话,然后使用刚创建的url启动dataTask 6.我们检查是否获取了数据,如果我们从服务器接收到数据,我们将以与第1部分相同的方式进行处理,并相应地调用完成处理程序 7.运行应用 很少有问题需要回答 Q1 @转义是什么? 答:我们希望完成对象不在函数getNames / getNamesFromServer的范围内,因此我们使用@escaping表示法来告诉编译器相同的对象 Q2为什么我们在Part2中不使用DispathQueue.global? 答:我们没有用相同的方法创建后台队列,因为URLSession自己处理它,它在内部剪切后台队列以发出http请求,我们只需要处理主队列即可。 Q3我们从哪里获得此服务器? A.上有一个网站http://jsonplaceholder.typicode.com/可以访问此网站以获取不同类型的Json数据

带有MVC的iOS Tableview

如何使其清晰并享受您的代码 如果您构建iOS项目,您已经知道这个事实:最常用的组件之一是UITableView 。 如果您尚未构建任何项目,您仍然可以在许多流行的iOS应用中看到UITableView :YouTube,Facebook,Twitter,Medium,大多数Messenger应用等。基本上,每次需要显示动态数量的在同一视图上的数据对象,请使用UITableView 。 另一个基本组件是CollectionView,我个人更喜欢使用它,因为它更灵活。 稍后我将发表另一篇有关CollectionView的文章。 因此,您想将UITableView添加到您的项目。 一种明显的方法是使用具有内置UITableView的UITableViewController 。 它可以通过简单的设置工作,您只需要添加数据数组并创建一个单元格即可。 它看起来很简单,并且可以按照我们需要的方式工作,除了以下几点: UITableViewController代码变得超长。 并且它打破了MVC模式。 什么是MVC?为什么我们需要考虑一下? 您可以查看这篇文章,其中对所有iOS体系结构模式都有很好的解释。 您不想处理所有这些模式吗? 无论如何,您可能仍想拆分您的一千行长的UITableViewController。 在上一篇文章中,我描述了将数据从模型传递到控制器的三种方法。 在本文中,我将使用委派方法向您介绍处理tableViews的方法。 这种方法使代码看起来非常整洁,模块化且可重用。 我们将不使用一个UITableViewController ,而是将其拆分为多个类: DRHTableViewController :我们将其设为 UIViewController的子类,并添加UITableView作为子视图 DRHTableViewCell : UITableViewCell的子类 DRHTableViewDataModel :它将使用委托进行API调用,创建数据并将数据返回给DRHTableViewController DRHTableViewDataModelModelItem :一个简单的类,将保存所有数据,这些数据将显示在DRHTableViewCell中 。 让我们从UITableViewCell开始。 第1部分:TableViewCell 从一个名为“单视图应用程序”的新项目开始,并删除默认的ViewController.swift和Main.storyboard文件。 我们将逐步创建所有需要的文件。 首先,创建一个UITableViewCell子类。 如果要使用XIB ,请选中“也创建XIB文件”。 在此示例中,我们将复制中型主页的简化版本。 因此,我们将需要添加以下子视图: 头像图片 名称标签 日期标签 文章标题 文章预览 以所需的方式应用“自动布局”,因为单元格设计不会影响我们在本教程中所做的任何事情。 为每个子视图创建一个出口。 在您的DRHTableViewCell.swift中,您将具有类似以下内容: 类DRHTableViewCell:UITableViewCell { @IBOutlet弱var […]

在键盘上浮动活动文本字段的更好方法

重用UIKit元素,集中观察者,简化设计。 您在上图中看到了什么? 一个有趣的建筑 设计 。 您还能观察到什么? 三次重复 模式 。 尽管重复模式在体系结构中是神圣的,但在其他地方却不那么受重视。 我们所有人都在开发具有某种形式的应用程序,通常用于捕获个人详细信息(例如注册)。 您必须向上移动活动文本字段,因为它原本在键盘后面。 为此,您必须观察键盘的UIKeyboardDidShow和UIKeyboardWillHide通知,以便您可以在键盘向上时对文本字段位置应用垂直偏移,而在关闭键盘时可以移除该偏移。 典型形式如下所示(从下面的代码片段创建)。 如果您从事的大型项目具有几种这样的形式,则可能发现自己不得不在需要该功能的每个ViewController中重复执行键盘通知观察代码。 但是,对于这样的表单,我们可以使用tableview而不是直接使用滚动视图,然后使用自定义的公共Tableview进行观察。 这是一个例子。 监听键盘显示更改的自定义表格视图 在这里,我们传入了将要坐在键盘上的视图(必须是weak property以避免保留周期)。 然后,我们创建一个协议,使用此自定义Tableview的所有类都必须遵守该协议。 接下来,在我们的注册视图控制器中,我们将使用自定义表KBTableView ,即KBTableView来监听键盘显示更改,而不是使用普通的表视图,并实现两种协议方法。 使用键盘侦听器TableView的ViewController 这就对了。 如果我们还有另一个带有窗体的viewcontroller,则它也只订阅KeyboardDisplayChangeProtocol协议,而不必观察键盘显示的变化。 如果您希望在此处查看我们的CustomCell : 如果您觉得这篇文章有用,请随时喜欢它,也欢迎您关注我们的出版物以跟踪后续文章。 谢谢!

TableViewCell管理のグッドプラクティス

Table,TableViewのCellはどのように管理していますか? 愚直に実装して,后から追加の要件が降って来たときに,DataSourceが目も当てられない状态になっていませんか? ではの记事では,TableViewのCellを良い感じに取り回すためのグッドプラクティスについてサンプルを交えて绍介したいと思います。 叩きとなるサンプルとして,TODOアプリを作成することを考えましょう。 要件 一番上にプロフィールのセクションを表示 カテゴリごとのTODOタスクを并べる 各カテゴリにはヘッダーを设ける この要件のTODOアプリを, 単纯に実装 中间表现を作成 抽象化 という3Stepで见ていきたいと思います。 単纯に実装していくと,以下のようになるかと思います。 表示するタスクの配列をプロパティとして持つDataSourceを作る 科の数 部ごとの行の数 科のヘッダータイトル 各行に表示する单元格 こんなにシンプルな要件なのにもう70行ですね… 辛いこと DataSourceのそれぞれのメソッドで开关文(或其他文)が乱立してしまい,DRYじゃない 查看のレイアウトが変わった际の影响范囲が大きい そこで,表示されるデータと表示するTableViewの间の中间表现として, 各节,行でTableViewに何を表示するかを表现する 二重配列 (外侧がsection,构成がrowを表す入れ子配列)を定义することで,上记の辛いことを解消していきたいと思います。 表示するタスクを二重配列として持つDataSourceを作る これにより, numberOfSections numberOfRowsInSection titleForHeaderInSection cellForRowAt で毎回indexPathによる分岐を作る必要がなくなりました。 科の数 部ごとの行の数 科のヘッダータイトル 各行に表示するCell 分岐の处理が共通化されて70行→ 55行とだいぶスッキリしましたね。 TableViewの状态を表す中间表现を二重配列として切り出すことができました。 Data,他の全てのDataSourceにおいて同じような处理を何度も书いていくのも面倒なので,これらを抽象化した衬底クラスStructuredTableCellDataSourceを作ります。 Table,TableViewの剖面,行を表す构造体を定义します。 TableCellSection.swift TableCellRow.swift そして,二重配列として表现していたTableViewの状态を, TableCellSectionの配列として持つStructuredTableCellDataSource を定义します。 表示するタスクをTableCellSectionの配列として持つStructuredTableCellDataSourceを作る UITableViewDataSourceの处理を共通化していきます。 (このあたりは先ほどとやっていることはほとんど同じですね) 科の数 部ごとの行の数 科のヘッダータイトル Cell,Cellの构成处理はまるっと抽象化できないので,次のように少し工夫してあげる必要があります。 […]

如何创建自定义表格视图单元格(快速)

这个故事最初发布在AppMakers.Dev 在iOS中,您可以使用“自动布局”来定义表格视图单元格的高度。 在本教程中,我们将向您展示如何使Table View Cells自动调整大小。 首先,创建一个简单的TableView,它属于您的ViewController。 创建名为Table QuoteCell的自定义TableViewCell类。 在StoryBoard中打开ViewController并将CellID添加为tableViewCell标识符。 将两个名为quoteLabel和authorLabel的标签添加到自定义单元格。 向它们添加约束。 在QuoteTableViewCell类中为这些标签设置IBOutlets。 我们的应用程序将显示引号。 假设我们要在TableView中包含以下带引号的数据。 在您的ViewController中添加dataForTableView变量。 让dataForTableView = [(“我没有失败。我刚刚找到了10,000种行不通的方法。”,“ Thomas A. Edison”),(“一个人不过是他思想的产物。他在想什么,他成为。”,“圣雄甘地”),(“业余者坐下来等待灵感,我们其余的人都站起来去上班。”,“斯蒂芬·金”),(“智慧不是教育的产物,而是终身尝试获得它。”,“阿尔伯特·爱因斯坦”)] 让我们设置TableView。 我们的ViewController将包含以下代码: // // ViewController.swift // SelfSizingTableViewCells // //由Apps-Top.com团队创建 // Apps-Top.com // 导入UIKit ViewController类:UIViewController,UITableViewDelegate,UITableViewDataSource { @IBOutlet弱var tableView:UITableView! 让dataForTableView = [(“我没有失败。我刚刚找到了10,000种行不通的方法。”,“ Thomas A. Edison”),(“一个人不过是他思想的产物。他在想什么,他成为。”,“圣雄甘地”),(“业余者坐下来等待灵感,我们其余的人都站起来去上班。”,“斯蒂芬·金”),(“智慧不是教育的产物,而是终身尝试获得它。”,“阿尔伯特·爱因斯坦”)] 覆盖func viewDidLoad(){ super.viewDidLoad() //加载视图后进行其他任何设置,通常是从笔尖进行。 self.tableView.delegate =自我 self.tableView.dataSource =自我 } 覆盖func didReceiveMemoryWarning(){ […]