Currently, I have a CustomTableViewCell that is used in four or 5 different places. The custom cell has a lazy loaded UILongPressGestureRecognizer property that gets added as a gesture recognizer in cellForRowAtIndexPath in the parent VC.
self.tableView.addGestureRecognizer(cell.longPress)
When a user initiates the long press, I want a toast notification to popup displaying some contextual information, and then to disappear after a few seconds. I've included this in my code for the CustomTableViewCell, but all of these decisions are starting to "smell." Is there a smarter, more logical way to be implementing these decisions?
This table view cell has the following code:
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()
}
I think it makes more sense for the TableView to know how to display a toast so I would create a protocol in your tableViewCell, so I would take the following steps.
So let's do responding to long press gesture first
Then extend your TableViewController to conform to your new protocol
Now, configuring your table view cell within your TableViewController configure your cell and assign the TableViewController as the longPressDelegate
This approach is nice because you can move the createToastNotification() method to your TableViewController and be responsible for creating toast (only once)
Then you can change createToastNotification to
Lastly for YourTableViewController, configuring toast, let's create a configureToastNotification(with title: String) like:
For the end, we remove a lot of the responsibility from YourTableViewCell and allow it to only delegate :