Tag: uitableview

如何创建自定义可移动UITableViewCell / UICollectionViewCell。

难度等级:容易 在本教程中,您将学习如何通过长按手势来制作可移动的表格视图单元格。 您可以在我的github页面上找到相同的教程。 bhaveshtandel17 / MovableTableViewCell MovableTableViewCell –在本教程中,您将学习如何通过长按手势来移动表格视图单元格。 github.com 怎么做? 添加UILongGestureRecognizer 处理UIGestureRecognizerState.began 处理UIGestureRecognizerState.changed 让我们开始吧!! 🎉

UITableViewCells的带有复选按钮的多行选择(以编程方式)

UITableViewCells具有流行的附件类型“ .checkmark”和导航的“编辑”按钮项中众所周知的编辑功能。 但是,“邮件和消息”应用程序中鲜为人知的功能之一是显示用于多行选择的圆形复选框的选项。 通过互联网组合在一起解决此问题后,希望我可以省去您的精力! 这是有关如何完成的快速演示: 在继续之前,我想提醒您仔细查看如何以编程方式添加tableView和导航栏。 您可以检查AppDelegate.swift和ViewController.swift以获取详细信息。 在viewDidLoad()中,添加以下两行。 第一行向导航控制器添加了一个编辑按钮,第二行实现了显示动画复选框的内置功能,该复选框允许用户一次选择多个单元格。 tableView.allowsMultipleSelectionDuringEditing = true self.navigationItem.rightBarButtonItem = editButtonItem 3.因为我们有不同的部分,所以我们需要实现以下功能: 4.我们只想编辑第一部分的行 5.现在我们需要告诉应用程序删除我们选择的行 6.请记住,由于tableView是子视图,因此我们需要显式更新其编辑状态 7.在底部添加带有删除按钮的工具栏 8.通过遍历所有选定的行并将其删除来实现删除按钮 您可以在此处下载整个示例应用程序:https://github.com/mrachamallu/MultiSelectExample

iOS TableView使用Swift预取数据源

Apple引入了用于在iOS 10中预取UITableView和UICollectionView的 API。这是有关如何实现UITableViewDataSourcePrefetching协议的简短故事。 总览 为了实现预取,我们向视图控制器确认了UITableViewDataSourcePrefetching协议,就像UITableViewDataSource和UITableViewDelegate一样 。 这使表视图的数据源可以在调用tableView(_:cellForRowAt 🙂数据源方法之前开始为单元格加载数据。 入门 将视图控制器设置为表视图预取数据源 tableView.prefetchDataSource =自我 在tableView(_:prefetchRowsAt :)的实现中,初始化指定索引路径中单元格所需的数据的异步加载。 func tableView(_ tableView:UITableView,prefetchRowsAt indexPaths:[IndexPath]){ 用于indexPaths中的indexPath { 警卫让_ = loadingOperations [indexPath]否则{返回} 如果让dataLoader = dataStore.loadPhoto(at:indexPath.row){ loadingQueue.addOperation(dataLoader) loadingOperations [indexPath] = dataLoader } } } 当表视图通知您tableView(_:cancelPrefetchingForRowsAt 🙂方法不再需要数据时,取消挂起的数据加载操作 func tableView(_ tableView:UITableView,cancelPrefetchingForRowsAt indexPaths:[IndexPath]){ 用于indexPaths中的indexPath { 如果让dataLoader = loadingOperations [indexPath] { dataLoader.cancel() loadingOperations.removeValue(forKey:indexPath) } } } 异步加载数据 与tableView(_:cellForRowAt […]

快速的文字游戏,第二部分

在本文的第一部分中,我介绍了一些基本的代码来生成UITableView,其中的重要内容是拖放简短论文的主要内容。 当然,如果没有可编辑的表格视图,它的用途将非常有限,所以我认为我要做第二部分。 UITableView的最终目标应像这样,可以内联编辑,插入和删除条目。 首先,我们需要设置一个自定义UITableCell类,其中包含一个UITextField,代码如下所示。 类myTableViewCell:UITableViewCell,UITextFieldDelegate { 让标签:UITextField var listItems:myItem? { didSet { label.text = listItems!.text } } 所需的init(coder aDecoder:NSCoder){ fatalError(“ init(coder :)尚未实现”) } 覆盖init(样式:UITableViewCellStyle,复用标识符:字符串?){ 标签= UITextField(框架:CGRect.null) label.textColor = UIColor.black label.font = UIFont.systemFont(ofSize:16) super.init(样式:样式,reuseIdentifier:reuseIdentifier) label.delegate =自我 label.contentVerticalAlignment = UIControlContentVerticalAlignment.center addSubview(label) } 让leftMarginForLabel:CGFloat = 16.0 覆盖func layoutSubviews(){ super.layoutSubviews() label.frame = CGRect(x:leftMarginForLabel,y:0,width:bounds.size.width — leftMarginForLabel,高度:bounds.size.height) } func textFieldShouldReturn(_ textField:UITextField)-> […]

让我们做得更好:UITableViewCell

每个iOS开发人员都会创建UITableViewCells,但让我们做得更好。 根据我的实践,这里有五个原则。 TL; DR 在自己的小腿上做; 将用户界面设为私有; 不要配置模型; 让他们暗恋; 重用之前重设。 完整示例应用程序的源代码: https : //github.com/alekseishirokov/medium-01-better-uitableviewcell 每次在情节提要中创建新的UITableViewController时,XCode都会创建一个空单元格原型。 这导致开发人员使用此模板将UI元素直接放置到此单元格视图中。 但这是一个坏习惯。 迟早,您的项目经理会要求您使用完全相同的单元格设计,但要使用另一个表。 当他们告诉我不仅要在人员的详细信息视图中还必须在部门的详细信息视图中显示文档列表时,我已经摆脱了这种行为。 我文档的单元格原型包含10个UILabel,2个UIImageViews和一堆棘手的约束。 尽管XCode具有复制粘贴命令,但这并不容易。 让我们做得更好:在自己的xib文件中创建UITableViewCell并在所需的任何表中重复使用。 这很容易做到。 按Cmd + N创建一个新文件。 然后选择iOS → Cocoa Touch Class 。 然后在下拉菜单的子类中选择UITableViewCell ,输入类名,并选中“ 同时创建XIB文件”复选框。 XCode创建两个文件: DocumentTableViewCell.swift和DocumentTableViewCell.xib 。 使用xib文件将UI元素放入单元格视图中。 使用swift文件将IBOutlet与这些UI元素绑定。 然后,您可以在表视图控制器中使用此DocumentTableViewCell ,如下所示: 这意味着我需要重构每个使用我的DocumentTableViewCell的表视图控制器,如下所示: 如今,我做得更好。 我将UI出口声明为单元格视图专用。 我仅使用configure方法将数据传递给UI元素: 在表视图控制器中,您只需将文档的优先级作为参数传递给configure方法。 直觉是, 优先级是数据,取决于单元格视图如何显示数据。 同样,在单元设计发生更改的情况下,也无需重构表视图控制器。 即使在教程中,也通常通过将模型对象传递给configure方法来用数据填充单元格: 这似乎是一个优雅的解决方案,但事实并非如此。 这会将单元格的视图与模型对象耦合在一起。 单元格视图取决于模型对象的结构。 但是,我们坚持的MVC模式就是将视图和模型分离。 我倾向于将数据作为单独的参数传递给configure方法: […]

将UITextView嵌入UITableViewCell中

在Workable,我们有一个称为评估的功能。 部分原因是可以填写面试套件,如下所示。 当我们开始研究如何实现此功能时,出现的一个想法是使用堆栈视图,但是用户创建了采访工具包,因此它们的大小可能会有所不同。 因此,我们选择使用UITableView作为此屏幕的主干。 毕竟它只是UITableViewCell中的UITextView,对吗? 在本文中,我将尝试列出我们面临的所有问题以及如何解决这些问题。 在演练结束时,将附上完整的解决方案。 在单元格内添加UITextView 我们创建了一个原型单元,并添加了UITextView,如下所示。 另外,不要忘记在UITextView的属性检查器中关闭 Scrolling Enabled属性。 这使UITextView具有取决于文本的固有内容大小,或者接近于我们稍后发现的文本大小。 现在,我们希望能够编辑文本。 简单,只需启用UITextView的`Editable`属性即可。 但是我们有一个小问题,我们希望UITableViewCell跟随UITextView的高度。 我们可以从单元格创建一个回调,以通知我们任何文本更改,如下所示: 在TextTableViewCell.swift中 @IBOutlet弱var textView:UITextView! var textChanged:(((String)-> Void)? 覆盖func awakeFromNib(){ super.awakeFromNib() textView.delegate =自我 } func textChanged(action:@escaping(String)-> Void){ self.textChanged =操作 } func textViewDidChange(_ textView:UITextView){ textChanged?(textView.text) } 在TableTableViewController.swift-> cellForRow中 cell.textChanged {[weak tableView](newText:String)在 } 注意:不要忘了在此闭包的捕获列表中使tableView变弱,因为您将得到一个保留周期。 tableView->单元格(UI),单元格-> tableView(关闭) 我们唯一要做的就是重新加载单元。 我们有多种方法可以做到这一点,因此我们将尝试最常见的一种方法tableView.reloadData()。 cell.textChanged {[weak tableView](_)in //可能的解决方案:1 […]

自定义表格视图单元格-以编程方式

更新:将文章和项目更新为Swift 3.0 在线上有很多帖子,介绍如何使用界面构建器配置动态表格视图单元。 但是,针对程序化编程的程序几乎不多。 而且由于有了NSLayoutAnchor,所以事情从未如此简单! 最后,您将知道如何使用AutoLayout基于标签内容创建动态高度的tableview单元。 入门项目 首先,让我们从以下启动项目开始。 该应用程序删除了Storyboard,并将View Controller推送到应用程序委托内的导航控制器上。 我们将要交互的主要文件如下 Book.swift —包含书籍名称和详细信息的模型类 BookTableViewCell.swift —符合UITableViewDataSource协议的空UITableViewCell子类 BookDataSource.swift —包含用于生成书籍清单的类方法 ViewController.swift —空的ViewController子类 配置TableView 在函数configureTableView(:)中,添加以下代码 tableview.estimatedRowHeight = 100 tableview.rowHeight = UITableViewAutomaticDimension tableview.registerClass(BookTableViewCell.self,forCellReuseIdentifier:bookCellReuseIdentifier) 通过更新estimatedRowHeight属性,我们获得了以下效果: 如果表格包含高度可变的行,则在表格加载时计算其所有高度可能会很昂贵。 使用估计可以使几何计算的某些成本从加载时间推迟到滚动时间。 创建自调整大小的表视图单元格时,需要设置此属性并使用约束来定义单元格的大小。 注意,我们还设置了tableview的rowHeight属性。 这样,我们就可以预期单元格的自调整大小行为。 此外,我注意到一些开发人员重写heightForRowAtIndexPath可以达到类似的效果。 由于以下原因,应避免这种情况。 使用tableView:heightForRowAtIndexPath:而不是rowHeight会对性能产生影响。 每次显示表视图时,它都会在委托中为其表的每一行调用tableView:heightForRowAtIndexPath:,这可能导致表视图具有大量行(大约1000或更多)而导致严重的性能问题。 registerClass只是用一个标识符注册我们的BookTableViewCell。 通过使用NSLayoutAnchor,我们将tableview的锚点固定到其superview。 在configureTableView(:)中添加以下代码 view.addSubview(tableview) tableview.translatesAutoresizingMaskIntoConstraints = false tableview.topAnchor.constraint(equalTo:view.topAnchor).isActive = true tableview.leadingAnchor.constraint(equalTo:view.leadingAnchor).isActive = true tableview.bottomAnchor.constraint(等于:view.bottomAnchor).isActive = true tableview.trailingAnchor.constraint(equalTo:view.trailingAnchor).isActive […]

UITableView中的粘性“标题”。

结果: 凉! 现在,我们需要调整滚动视图内容的高度,以处理整个表视图内容+标头。 不幸的是,我无法通过scrollView.contentSize属性执行此操作 ,它什么也不做。 为此,我创建了rootContainerView 。 要更改高度,我们实际上需要一个锚点,将其添加并与代码连接。 而使一切正常的最后一件事。 调用tableView.layoutIfNeeded()以重新计算表格内容的高度,并将此内容大小的高度设置为我们先前创建的高度约束。 在下面的屏幕截图中完成了控制器代码和层次结构。 已完成的代码 GistBox代码段 完成!☺️

在Swift中绘制带有尾巴的消息气泡

消息传递应用程序中的一个常见主题是使消息气泡带有尾巴,这比将一堆块彼此叠放更好,并且这是区分谁发送了特定消息的简便方法。 尽管在您现在的iOS开发经验中,您可能会想知道如何创建这些自定义视图,所以在这篇文章中,我将向您展示如何制作自己的视图! 注意:对于本教程,我已经准备了一个在Github上可用的项目,该项目具有动态调整UITableViewCell设置的大小。 这是使用Xcode 8.3.3在Swift 3中编写的。 贝济耶救援之路 创建一个方形的消息单元并不难,即使是圆角的消息单元也不错,但是您必须改变通常创建单元的方式,以便在消息底部添加一条尾巴。 在下面,我将指导您完成一些步骤,不仅在消息单元下方绘制一条尾巴,还根据发送消息的人将其向左或向右绘制,类似于iMessage。 为了获得最终结果,我们需要使用UIBezierPath绘制消息气泡的形状,然后用所需的颜色填充它。 乍一看似乎令人望而生畏,但想起来就像在纸上画一个正方形一样。 您从给定点开始,思考(0,0),然后开始将第一条线绘制到下一个点(1,0)。 再过三边,您又回到起点,准备关闭形状并填充它。现在,我们只需要在代码中执行相同的操作即可! 绘制邮件正文 跳至MessageBubbleView类,让我们开始在draw(_ rect)编写代码。 (删除调用super.drawRect因为我们将提供自己的绘图代码。)现在,我们可以使用以下代码开始路径: 让bezierPath = UIBezierPath() bezierPath.move(收件人:CGPoint(x:rect.minX,y:rect.minY)) move视为拿起铅笔并将其放置在给定点的代码。 这将是我们信息泡沫的起点。 现在我们要画顶线。 bezierPath.addLine(至:CGPoint(x:rect.maxX,y:rect.minY)) 这将在rect的最右边绘制一条线,即maxX 。 现在,我们可以遵循相同的逻辑来绘制其他三个边缘。 bezierPath.addLine(至:CGPoint(x:rect.maxX,y:rect.maxY-10.0)) bezierPath.addLine(至:CGPoint(x:rect.minX,y:rect.maxY-10.0)) bezierPath.addLine(至:CGPoint(x:rect.minX,y:rect.minY)) 现在您可能想知道为什么我没有一直画线一直到rect或maxY的底部边缘。 这是因为我为绘制尾巴留了10.0点的空间。 我鼓励调整这些值,并查看您自己的代码中的不同结果! 画尾巴 现在添加尾巴。 我们将在这里再次使用move功能。 就像您从rect的左上边缘(我们刚刚结束最后一行的地方)拿起铅笔并将其移动到尾巴的起点一样。 在此示例中,我将绘制一条指向右下方的尾巴,然后绘制一条平坦的边缘,该边缘再次向上并与我们的邮件正文相遇。 bezierPath.move(至:CGPoint(x:rect.maxX-25.0,y:rect.maxY-10.0)) bezierPath.addLine(至:CGPoint(x:rect.maxX-10.0,y:rect.maxY)) bezierPath.addLine(至:CGPoint(x:rect.maxX-10.0,y:rect.maxY-10.0)) 我们有自己的形状! 但是,如果您运行该代码,则会发现看不到它。 这是因为我们需要关闭路径并填写。 UIColor.lightGray.setFill() bezierPath.fill() bezierPath.close() 大! 我们将路径封闭并用浅灰色填充。 现在,我们的draw方法应如下所示: 覆盖func draw(_ rect:CGRect){ 让bezierPath […]

在Swift(2)中使用UITableView-与RxSwift

正如我们在上一篇文章中介绍了UITableView的基本用法之后,这次我们将将该示例转换为一个使用RxSwift处理UITableView 。 RxSwift是一个更高级的主题。 请注意,这个故事仅演示了基础知识,但是可以肯定的是,如果广泛且正确地使用它,它可以将您和您的应用程序提升到另一个层次。 本教程的源代码可在Github上获得。 我们将从创建另一个安装了Cocoapods和RxSwift Xcode项目开始。 $ pod init 将RxSwift添加到Podfile 。 …#UITableView吊舱“ RxSwift”的吊舱 豆荚“ RxCocoa” … 安装pod并打开UITableView.xcworkspace 。 $ pod安装 初始设置 首先通过在UIViewController导入RxSwift和RxCocoa ,然后我们可以将代码转换为Rx样式。 导入RxSwift 进口RxCocoa 这次,我们还需要在UITableView通过以下JSON显示数据。 // travel.json [ { “名称”:“香港”, “ desc”:“我住的地方。”, “ url”:“ https://zh.wikipedia.org/wiki/香港 }, { “名称”:“新加坡”, “ desc”:“一个干净整洁的地方。”, “ url”:“ https://zh.wikipedia.org/wiki/新加坡” }, { “ name”:“ Japan”, “ desc”:“喜欢那些美味的寿司和生鱼片。”, “ url”:“ https://zh.wikipedia.org/wiki/日本” […]