What I want to do (verbatim): Hold a tableview cell for specified amount of time. Once it reaches that time period, the cell height increases gradually. When I release my finger, the cell height stops growing.
What I have: I have several tableViewCells. After pressing on a cell for a specified amount of time using:
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: Selector("longPress:"))
longPressRecognizer.minimumPressDuration = 1.0s
longPressRecognizer.delegate = self
self.view.addGestureRecognizer(longPressRecognizer)
I wanted to increase the cell height. But I couldn't do that without knowing at which row the touch was located, so I got up to here:
func longPress(longPressGestureRecognizer: UILongPressGestureRecognizer) {
if longPressGestureRecognizer.state == UIGestureRecognizerState.began {
let touchPoint = longPressGestureRecognizer.location(in: self.tableView)
if let indexPath = tableView.indexPathForRow(at: touchPoint) {
//let cell = tableView.cellForRow(at: indexPath)
}
}
}
I thought about controlling the rowHeight, but that's solely within the tableView functions so I did not know how to call it.
I am unsure how to proceed. And I am not looking for anything that has to do with .beginUpdates and .endUpdates because I want the cell growth to be gradual and preferably animated.
Any help would be greatly appreciated, as I have been searching for answers to this specific problem for quite a long time.
code that includes the rowHeight declaration:
override func viewDidLoad() {
super.viewDidLoad()
// let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: Selector("longPress:"))
// longPressRecognizer.minimumPressDuration = 1.0 // 1 second press
// longPressRecognizer.delegate = self
// self.view.addGestureRecognizer(longPressRecognizer)
tableView.delegate = self
tableView.dataSource = self
tableView.allowsSelection = false
self.tableView.reorder.delegate = self
view.backgroundColor = UIColor(red:0.64, green:0.93, blue:0.78, alpha:1.0)
tableView.backgroundColor = UIColor.clear
tableView.rowHeight = 84
tableView.rowHeight = UITableViewAutomaticDimension
// Do any additional setup after loading the view.
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
I don't like to explain things in details using words, so instead of a long answer, I will just include a relatively short code (available also as gist) that contains comments explaining the basics. I haven't really paid a lot of attention to architecture and clean code, I just focused on getting the task done. Take the code as such - try to make it better in your codebase.
Anyway, the code should be pretty clear and self-explanatory, but I would like to just sketch a big picture for you before you dive into it. In the solution, I keep the heights in an array of
CGFloat
(variablecellHeights
) and modify a height for a given row by changing the corresponding height in an array. That array serves as a basis forheightForRowAt
implementation.When long press begins, I start a timer, that every 0.1 seconds updates the height for the selected row by modifying the height in the
cellHeights
array and telling thetableView
to redraw itself. That happens until the limit is reached for that given row and then I simply cancel (invalidate) the timer.If the long press ends before the limit height is reached, I just explicitly cancel the timer, so that the cell stops enlarging when the user releases the press.
And that's it. I suggest you take the
EnlargingCellsOnLongPressController
gist (or the one below, it is the same code), try it on your own device, read the code along with the comments, and I believe you should be able to implement it in your own situation.UPDATE
For the sake of completeness, I have create a gist using autolayout and
UITableViewAutomaticDimension
, if you ever decide to use that instead ofheightForRowAt
. But the principle is the same.