使用自定义 UITableViewCell 显示 Toast 弹出窗口的模式
Patterns for Showing a Toast Popup with Custom UITableViewCell
目前,我有一个 CustomTableViewCell
在四五个不同的地方使用。自定义单元格有一个延迟加载的 UILongPressGestureRecognizer
属性,它作为手势识别器添加到父 VC 的 cellForRowAtIndexPath
中。
self.tableView.addGestureRecognizer(cell.longPress)
当用户启动长按时,我希望弹出 toast 通知以显示一些上下文信息,然后在几秒钟后消失。我已将其包含在 CustomTableViewCell
的代码中,但所有这些决定都开始 "smell." 是否有更智能、更合乎逻辑的方式来实施这些决定?
此 table 视图单元格具有以下代码:
weak var parentTableView: UITableView?
lazy var longPress: UILongPressGestureRecognizer = {
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressSelector))
longPress.minimumPressDuration = 0.5
longPress.delegate = self
return longPress
}()
func longPressSelector(_ longPress: UILongPressGestureRecognizer!) {
if let tableView = self.parentTableView {
let point = longPress.location(in: tableView)
let indexPath = tableView.indexPathForRow(at: point)
if ((indexPath! as NSIndexPath).section == 0 && longPress.state == .began) {
// do some work
// Show informational popup
let toast = createToastNotification(withTitle: addedSong.name)
Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) { (timer) -> Void in
UIView.animate(withDuration: 1.0) { () -> Void in
toast.alpha = 0.0
toast = nil
}
}
}
}
}
func createToastNotification(withTitle title: String) -> UIView {
if let tableView = self.parentTableView {
let windowFrame = tableView.superview?.bounds
let height:CGFloat = 145, width: CGFloat = 145
let x = (windowFrame?.width)! / 2 - width / 2
let y = (windowFrame?.height)! / 2 - height / 2
let toast = EnsembleToastView.create()
toast.frame = CGRect(x: x, y: y, width: width, height: height)
toast.songLabel.text = title
toast.layer.cornerRadius = 5
tableView.superview?.addSubview(toast)
return toast
}
return UIView()
}
我认为 TableView 知道如何显示 toast 更有意义,因此我会在您的 tableViewCell 中创建一个协议,因此我将采取以下步骤。
- 让 TableViewController 负责:
- 创建 toast(仅一次)
- 正在配置 toast
- 敬酒
- 响应长按手势
- 正在配置您的 table 视图单元格
- 只允许 YourTableViewCell 委托
所以让我们先响应长按手势
protocol TableViewCellLongPressDelegate {
func tableViewCellHadLongPress(_ cell: YourTableViewCell)
}
然后扩展您的 TableViewController 以符合您的新协议
extension YourTableViewController : TableViewCellLongPressDelegate {
func tableViewCellHadLongPress(_ cell: YourTableViewCell){
//configure toast based on which cell long pressed
configureToastNotification(with title: cell.title){
//show toast
}
}
现在,在您的 TableViewController 中配置您的 table 视图单元格 配置您的单元格并将 TableViewController 指定为 longPressDelegate
let cell = YourTableViewCell.dequeue(from: self.tableView)!
//configure cell
cell.tableViewCellLongPressDelegate = self
这种方法很好,因为您可以将 createToastNotification() 方法移动到您的 TableViewController 并负责创建 toast(仅一次)
var toastNotification : UIView?
viewDidLoad(){
//yatta yatta
toastNotification = createToastNotification()
}
那你可以把createToastNotification改成
func createToastNotification() -> UIView? {
let windowFrame = self.bounds
let height:CGFloat = 145, width: CGFloat = 145
let x = (windowFrame?.width)! / 2 - width / 2
let y = (windowFrame?.height)! / 2 - height / 2
let toast = EnsembleToastView.create()
toast.frame = CGRect(x: x, y: y, width: width, height: height)
toast.layer.cornerRadius = 5
self.addSubview(toast)
return toast
}
最后,对于 YourTableViewController,配置 toast,让我们创建一个 configureToastNotification(标题:字符串),例如:
func configureToastNotification(with title: String){
if let toast = self.toastNotification {
toast.songLabel.text = title
}
}
最后,我们从 YourTableViewCell 中删除了很多责任,允许它只委托 :
protocol TableViewCellLongPressDelegate : class {
func tableViewCellHadLongPress(_ cell: YourTableViewCell)
}
class YourTableViewCell : UITableViewCell {
//initializers
weak var longPressDelegate: TableViewCellLongPressDelegate?
lazy var longPress: UILongPressGestureRecognizer = {
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressHappened))
longPress.minimumPressDuration = 0.5
longPress.delegate = self
return longPress
}()
func longPressHappened() {
self.longPressDelegate?.tableViewCellHadLongPress(self)
}
}
目前,我有一个 CustomTableViewCell
在四五个不同的地方使用。自定义单元格有一个延迟加载的 UILongPressGestureRecognizer
属性,它作为手势识别器添加到父 VC 的 cellForRowAtIndexPath
中。
self.tableView.addGestureRecognizer(cell.longPress)
当用户启动长按时,我希望弹出 toast 通知以显示一些上下文信息,然后在几秒钟后消失。我已将其包含在 CustomTableViewCell
的代码中,但所有这些决定都开始 "smell." 是否有更智能、更合乎逻辑的方式来实施这些决定?
此 table 视图单元格具有以下代码:
weak var parentTableView: UITableView?
lazy var longPress: UILongPressGestureRecognizer = {
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressSelector))
longPress.minimumPressDuration = 0.5
longPress.delegate = self
return longPress
}()
func longPressSelector(_ longPress: UILongPressGestureRecognizer!) {
if let tableView = self.parentTableView {
let point = longPress.location(in: tableView)
let indexPath = tableView.indexPathForRow(at: point)
if ((indexPath! as NSIndexPath).section == 0 && longPress.state == .began) {
// do some work
// Show informational popup
let toast = createToastNotification(withTitle: addedSong.name)
Timer.scheduledTimer(withTimeInterval: 2.0, repeats: false) { (timer) -> Void in
UIView.animate(withDuration: 1.0) { () -> Void in
toast.alpha = 0.0
toast = nil
}
}
}
}
}
func createToastNotification(withTitle title: String) -> UIView {
if let tableView = self.parentTableView {
let windowFrame = tableView.superview?.bounds
let height:CGFloat = 145, width: CGFloat = 145
let x = (windowFrame?.width)! / 2 - width / 2
let y = (windowFrame?.height)! / 2 - height / 2
let toast = EnsembleToastView.create()
toast.frame = CGRect(x: x, y: y, width: width, height: height)
toast.songLabel.text = title
toast.layer.cornerRadius = 5
tableView.superview?.addSubview(toast)
return toast
}
return UIView()
}
我认为 TableView 知道如何显示 toast 更有意义,因此我会在您的 tableViewCell 中创建一个协议,因此我将采取以下步骤。
- 让 TableViewController 负责:
- 创建 toast(仅一次)
- 正在配置 toast
- 敬酒
- 响应长按手势
- 正在配置您的 table 视图单元格
- 只允许 YourTableViewCell 委托
所以让我们先响应长按手势
protocol TableViewCellLongPressDelegate {
func tableViewCellHadLongPress(_ cell: YourTableViewCell)
}
然后扩展您的 TableViewController 以符合您的新协议
extension YourTableViewController : TableViewCellLongPressDelegate {
func tableViewCellHadLongPress(_ cell: YourTableViewCell){
//configure toast based on which cell long pressed
configureToastNotification(with title: cell.title){
//show toast
}
}
现在,在您的 TableViewController 中配置您的 table 视图单元格 配置您的单元格并将 TableViewController 指定为 longPressDelegate
let cell = YourTableViewCell.dequeue(from: self.tableView)!
//configure cell
cell.tableViewCellLongPressDelegate = self
这种方法很好,因为您可以将 createToastNotification() 方法移动到您的 TableViewController 并负责创建 toast(仅一次)
var toastNotification : UIView?
viewDidLoad(){
//yatta yatta
toastNotification = createToastNotification()
}
那你可以把createToastNotification改成
func createToastNotification() -> UIView? {
let windowFrame = self.bounds
let height:CGFloat = 145, width: CGFloat = 145
let x = (windowFrame?.width)! / 2 - width / 2
let y = (windowFrame?.height)! / 2 - height / 2
let toast = EnsembleToastView.create()
toast.frame = CGRect(x: x, y: y, width: width, height: height)
toast.layer.cornerRadius = 5
self.addSubview(toast)
return toast
}
最后,对于 YourTableViewController,配置 toast,让我们创建一个 configureToastNotification(标题:字符串),例如:
func configureToastNotification(with title: String){
if let toast = self.toastNotification {
toast.songLabel.text = title
}
}
最后,我们从 YourTableViewCell 中删除了很多责任,允许它只委托 :
protocol TableViewCellLongPressDelegate : class {
func tableViewCellHadLongPress(_ cell: YourTableViewCell)
}
class YourTableViewCell : UITableViewCell {
//initializers
weak var longPressDelegate: TableViewCellLongPressDelegate?
lazy var longPress: UILongPressGestureRecognizer = {
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(longPressHappened))
longPress.minimumPressDuration = 0.5
longPress.delegate = self
return longPress
}()
func longPressHappened() {
self.longPressDelegate?.tableViewCellHadLongPress(self)
}
}