使用自定义UITableViewCell显示Toast Popup的模式

时间:2017-01-20 16:43:01

标签: ios swift design-patterns swift3 cocoa-design-patterns

目前,我有一个CustomTableViewCell用于四个或五个不同的地方。自定义单元格具有延迟加载的UILongPressGestureRecognizer属性,该属性在父VC中的cellForRowAtIndexPath中添加为手势识别器。

self.tableView.addGestureRecognizer(cell.longPress)

当用户启动长按时,我想要一个Toast通知弹出显示一些上下文信息,然后在几秒后消失。我已经在CustomTableViewCell的代码中加入了这个,但所有这些决定都开始嗅到了。#34;是否有更智能,更合理的方式来实施这些决策?

此表格视图单元格具有以下代码:

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()
}

1 个答案:

答案 0 :(得分:1)

我认为TableView知道如何显示toast更有意义,所以我会在tableViewCell中创建一个协议,所以我会采取以下步骤。

  • 让TableViewController负责:
    • 创建吐司(仅一次)
    • 配置toast
    • 显示吐司
    • 回应长按手势
    • 配置表格视图单元格
  • 允许YourTableViewCell仅委派

让我们先做回复长按手势

n()

然后扩展TableViewController以符合您的新协议

library(dplyr)
library(tidyr)
df %>% 
    select(-L1) %>% 
    gather(Var, Val, -Name) %>% 
    filter(Val>0) %>% 
    group_by(Name) %>%
    summarise(Total = n())
# A tibble: 2 × 2
#   Name Total
#  <chr> <int>
#1  Carl     4
#2   Joe     4

现在,在TableViewController中配置表格视图单元格配置您的单元格并将TableViewController指定为longPressDelegate

protocol TableViewCellLongPressDelegate {
    func tableViewCellHadLongPress(_ cell: YourTableViewCell)
}

这种方法很好,因为你可以将createToastNotification()方法移动到TableViewController,负责创建toast(只有一次)

extension YourTableViewController : TableViewCellLongPressDelegate {
    func tableViewCellHadLongPress(_ cell: YourTableViewCell){
         //configure toast based on which cell long pressed
         configureToastNotification(with title: cell.title){
         //show toast
    }
}

然后您可以将createToastNotification更改为

let cell = YourTableViewCell.dequeue(from: self.tableView)!
//configure cell
cell.tableViewCellLongPressDelegate = self

最后,对于YourTableViewController,配置toast ,让我们创建一个configureToastNotification(标题:String),如:

var toastNotification : UIView?
viewDidLoad(){
    //yatta yatta
    toastNotification = createToastNotification()
}

最后,我们从YourTableViewCell中删除了很多责任,仅允许它委托

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
}