SwiftyComments
基于 UITableViewDataSource 的组件,用于显示可展开/可折叠的评论层次。
安装
手动
只需将项目中的 SwiftyComments/Classes
文件夹中的 .swift
文件复制到您的项目中。
CocoaPod
将以下行添加到您的 Podfile 中
pod 'SwiftyComments', :git => 'https://github.com/tsucres/SwiftyComments.git'
使用
概述
基本上,你所要做的就是
- 导入
import SwiftyComments
- 定义你的评论视图(通常包含发布者名称、日期时间、评论内容等)。这个视图将是每个
CommentCell
(UITableViewCell
的子类)的主要子视图; - 通过
CommentCell
类的可用属性来自定义表格视图的外观; - 向
CommentsViewController
提供你的模型。
细节
以下是关于之前步骤的更多详细信息
1) 构建你的 CommentCell
CommentCell
主要是显示你的评论和缩进的一个 UIView。这里有一个基本的实现
class YourCommentCell: CommentCell {
override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
// YourCommentView is a UIView aimed to contain all the info about a comment (poster's name, date, body, ...)
self.commentViewContent = YourCommentView()
// Customisation...
// ...
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
2) 自定义你的单元格
你可以通过 CommentCell
类的多个属性来自定义评论视图的周围环境(如缩进、边距)
// Margin on top of a root comment
self.rootCommentMarginColor = ...
self.rootCommentMargin = ...
// Margin on top of any non-root comment
self.commentMarginColor = ...
self.commentMargin = ...
// Space on the left of any indented comment
self.identationColor = ...
// Vertical line between the indentation space and the comment
self.indentationIndicatorColor = ...
self.indentationIndicatorThickness = ...
// Whether to continue the indentyation indicator on all the child comments or not
self.extendIndentationIndicators = ...
// thickness of the indentation offset per level
self.indentationUnit = ...
3) 加载数据
CommentsViewController
类继承自 UITableViewController
并负责加载数据。你需要做的是将 allComments
属性填充为你的模型,并重写 tableView(_:cellForRowAt:)
方法
class YourCommentsViewController: CommentsViewController {
private let commentCellId = "commentCellId"
var allComments: [YourCommentModel] = [] // All the comments (nested, not in a linear format)
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(SimpleCommentCell.self, forCellReuseIdentifier: commentCellId)
currentlyDisplayed = allComments // Assuming your models are loaded in allComments
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> CommentCell {
let commentCell = tableView.dequeueReusableCell(withIdentifier: commentCellId, for: indexPath) as! YourCommentCell
let comment = currentlyDisplayed[indexPath.row] as! YourCommentModel
commentCell.level = comment.level
// commentCell.body = ...
return commentCell
}
}
注意 你的模型必须符合 AbstractComment
协议
public protocol AbstractComment: class {
var replies: [AbstractComment]! { get set }
var level: Int! { get set }
weak var replyTo: AbstractComment? { get set }
}
默认情况下,当评论展开时,表格将滚动以便显示回复。你可以通过 makeExpandedCellsVisible
属性关闭此功能。
此外,可以将 fullyExpanded
属性设置为 true
以从完全展开的表格视图开始。
tableView的整体结构
以下图片展示了tableView的结构
1
表示整个CommentCell
2
是分配给cell的commentViewContent
属性的UIView
3
是 缩进空间,您可以通过CommentCell
的indentationUnit
和indentationColor
属性进行个性化设置4
的颜色和粗细可以通过CommentCell
的commentMarginColor
和commentMargin
属性进行个性化设置5
也可以通过indentationIndicatorColor
和indentationIndicatorThickness
进行修改- 与
6
类似,可以通过rootCommentMarginColor
和rootCommentMargin
进行设置
AttributedStrings
您可以使用具有 NSAttributedString
的 UITextView
在注释内容视图中轻松添加特殊样式(标题、链接、段落间距、粗体/斜体字体等)。
尽管如此,如果您的注释内容是HTML格式,您可能需要重新考虑使用 DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html
选项的计划。即使这种方法非常简单直接,但它并不高效,并且加载字符串需要很长时间(在我的经验中,约为.15 - .2秒)。由于单元格的高度是基于其内容自动计算的,这种延迟会导致故障/延迟。
一个替代方案(如 HNCommentsViewController
示例所示)是自行解析HTML并手动添加属性来构建 NSAttributedString
。
这取决于您的评论格式的复杂性,可能更难实现,但效率高得多。
如果不信任我,请在 HNCommentsViewController.swift
中查看并取消加载注释的注释部分...
此示例使用 SwiftScanner 解析hackernews评论的HTML。请查看 HNCommentContentParser.swift
文件以了解更多有关如何构建 AttributedString
的详细信息。
CommentsViewDelegate
public protocol CommentsViewDelegate: class {
func commentCellExpanded(atIndex index: Int)
func commentCellFolded(atIndex index: Int)
}
您可以实现此协议,并正确设置 CommentsViewController
的 delegate
属性,以便在单元格展开/折叠时接收到通知。
例如,您可以使用此功能在折叠时最小化评论。查看 RedditCommentsViewController
的示例获取更多细节。
滑动隐藏
SwipeCellKit 被用于在每个评论单元格上添加 "滑动隐藏" 动作。
启用/禁用
您可以使用 CommentsViewController
的 swipeToHide
属性来禁用此功能。
自定义
外观
通过 CommentsViewController
的 swipeActionAppearance
属性,您可以自定义滑动操作的外观。这样就可以改变所有以下滑动操作属性:
open var swipeActionColor: UIColor
open var swipeActionHighlightedColor: UIColor
open var swipeActionText: String
open var swipeActionTextColor: UIColor
open var swipeActionHighlightedTextColor: UIColor
open var swipeActionTextFont: UIFont
open var swipeActionImage: UIImage
open var swipeActionHighlightedImage: UIImage
有关更多信息,请参阅 SwipeCellKit 的官方文档。
您可以通过(仔细地)重写以下方法进一步进行自定义:
public func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]?
添加操作
要添加操作,您必须重写 editActionsForRowAt
方法。
override public func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]? {
// Retrieve the "collapseAction"
var actions = super.tableView(tableView, editActionsForRowAt: indexPath, for: orientation)
// Create you additional action(s) according to the documentation of SwipeCellKit
let oneMoreAction = SwipeAction(...)
actions.append(oneMoreAction)
return actions
}
备注
相较于iOS 8中引入的默认UITableViewRowAction,更倾向于使用SwipeCellKit。主要原因在于UITableViewRowAction在处理单元格的调整大小动画(折叠时)方面表现不佳:随着单元格尺寸减小,UITableViewRowAction始终保持最初的大小并与其他单元格重叠。另一个原因是SwipeCellKit的更强大的自定义性。
示例
要运行示例项目,请克隆仓库,并从示例目录中运行pod install
。
本项目对CommentsViewController
有四种不同的实现方法
SimpleCommentsViewController
展示了基本实现;ImgurCommentsViewController
是Imgur iOS应用程序评论系统的复制品;RedditCommentsViewController
是Reddit iOS应用程序评论系统的复制品;HNCommentsViewController
展示了使用AttributedStrings的实现。
待办事项
- 对tableView进行更多抽象
- 移除
init(style: UITableViewCellStyle, reuseIdentifier: String?)
- 覆盖
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> CommentCell
- 移除
- iOS 11中添加/删除行动画有些奇怪..有解决方案吗?
- 标记评论为展开/折叠,以便在展开评论时保持其回复的展开/折叠状态。目前,当一个折叠回等的评论被折叠后再次展开,其回复也会被展开。
- 更好的文档/README
许可证
SwiftyComments遵从MIT许可证。更多详情请参阅LICENSE文件。