fellows!
I'm trying to make an animation of an image in my tableViewCell. My intent is to get an imageView that is in a tableViewCell, add it to exactly the same place in a view, and then use scale animation. Currently, my code looks as below, however, I need to find a cell center point in every period of time (after scrolling too), that I can add image view exactly in the same place. The value of cellRect.origin.y constantly increases, whereas I need it to be exactly center.y point of my tableView cell. Could you please tell me where my mistake is?
Thank you in advanse!
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath) as! TableViewCell
cell.animateImageView = { [weak self]
guard let self = self else { return }
tableView.layoutSubviews()
var cellRect = self.view.convert(tableView.rectForRow(at: indexPath), to: self.tableView)
cellRect.origin.x = UIScreen.main.bounds.midX - (cell.photoImageView.frame.width / 2)
cellRect.origin.y = cellRect.origin.y + (cell.photoImageView.frame.height / 2)
UIView.animate(withDuration: 3) {
} completion: { isFinished in
}
}
}
If I understand you correctly, this is your goal
If yes, there here are my thoughts
I feel this line has the first issue:
var cellRect
= self.view.convert(tableView.rectForRow(at: indexPath),
to: self.tableView)
Let's take a look at the convert function in the docs
Converts a rectangle from the receiver’s coordinate system to that of another view.
Parameters
rect
A rectangle specified in the local coordinate system (bounds) of the receiver.
view
The view that is the target of the conversion operation. If view is nil, this method instead converts to window base coordinates. Otherwise, both view and the receiver must belong to the same UIWindow object.
The receiver
here is your cell's image view
which you want to recreate so you should not call self.view.convert
, it should be cell.photoImageView.convert
The rect
parameter is the bounds of your tapped cell's image view and the to
parameter is self.view
as you want to convert the image view's coordinates in the cell to the coordinates in the main view of the view controller.
Beyond that I am not sure of the purpose of these as you will get the frame from the above function so I removed them but you can add it back if it makes sense to your application.
cellRect.origin.x
= UIScreen.main.bounds.midX - (cell.photoImageView.frame.width / 2)
cellRect.origin.y
= cellRect.origin.y + (cell.photoImageView.frame.height / 2)
So this is how I changed the function:
func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath)
{
// Retrieved the actual cell that was tapped
// same as what you did
let cell
= tableView.cellForRow(at: indexPath) as! TableViewCell
// Here I made a change based on my explanation above
let cellRect =
cell.photoImageView.convert(cell.photoImageView.bounds,
to: view)
// I created a blue view just for demo
let aView = UIView(frame: cellRect)
aView.backgroundColor = .blue
view.addSubview(aView)
}
If you end it here, you will get this result
The blue view added perfectly where we want it
Now to complete the rest with animation is quite simple after we accomplished the tricky part and here is the full function
func tableView(_ tableView: UITableView,
didSelectRowAt indexPath: IndexPath)
{
// Retrieved the actual cell that was tapped
let cell
= tableView.cellForRow(at: indexPath) as! TableViewCell
// Here I made a change based on my explanation above
let cellRect =
cell.photoImageView.convert(cell.photoImageView.bounds,
to: view)
let animateImageView = UIImageView(frame: cellRect)
animateImageView.image = cell.photoImageView.image
animateImageView.clipsToBounds = true
view.addSubview(animateImageView)
UIView.animate(withDuration: 2.0)
{ [weak self] in
if let strongSelf = self
{
animateImageView.frame = strongSelf.view.bounds
}
} completion: { (success) in
if success
{
// animation completed, do what you want
// like push your VC
}
}
}
The end result I believe is what you want
I hope this helps you get you closer to your desired result