Animation of UI View in table view cell is not consistent

70 Views Asked by At

For some reason, when the cell that's being animated goes off-screen and comes back, the animation speed changes. Upon tapping the cell, a new view controller is opened. After I returned from the view controller to the initial view, the animation stopped altogether.

So far, I've tried to start the animation in cellForRowAt, but that didn't seem to work either.

Link to video for the problem: https://drive.google.com/file/d/1jt5IM1Ya4gIfzb1ok-NTmS2QTnrSTNoG/view?usp=sharing

Below is the code for willDisplay cell and the functions for animating my ui view inside my table view cell.

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if let cell = cell as? DirectionSummaryTableViewCell {
            if let isLive = cell.isLive {
                if isLive {
                    cell.animateBusStatusBackground()
                } else {
                    cell.removeAnimation()
                }
            }
        }
    }
func animateBusStatusBackground() {

        UIView.animate(withDuration: 1.0, delay: 0.0, options: [.repeat, .autoreverse, .curveEaseInOut], animations: { [weak self] in
            if self?.busStatusView.backgroundColor == .red {
                self?.busStatusView.backgroundColor = .grey6
            } else {
                self?.busStatusView.backgroundColor = .red
            }
        }, completion: nil)
    }
func removeAnimation() {
        self.busStatusView.layer.removeAllAnimations()
        self.layer.removeAllAnimations()
        self.layoutIfNeeded()
    }
 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        guard let cell = tableView.dequeueReusableCell(withIdentifier: DirectionSummaryTableViewCell.identifier, for: indexPath) as?  DirectionSummaryTableViewCell else { return UITableViewCell() }

        cell.configure(with: viewModel.placeToPlacePossibleDirections[indexPath.section][indexPath.row].directions, 
tripDuration: viewModel.placeToPlacePossibleDirections[indexPath.section][indexPath.row].tripTime,
destinationArrivalTime:viewModel.placeToPlacePossibleDirections[indexPath.section][indexPath.row].reachBy,
busDepartureTime: viewModel.placeToPlacePossibleDirections[indexPath.section][indexPath.row].directions.routes[0].departureTime, 
startLocation: viewModel.placeToPlacePossibleDirections[indexPath.section][indexPath.row].directions.routes[0].stops[0].name, addFullLabel: true, 
isLive: viewModel.placeToPlacePossibleDirections[indexPath.section][indexPath.row].responseType == "realtime")

        return cell
    }
func configure(with directions: PlaceToPlaceBusDirections, tripDuration: Double, destinationArrivalTime: String, busDepartureTime: String, startLocation: String, addFullLabel: Bool, isLive: Bool) {
        self.directions = directions
        self.isLive = isLive
        self.collectionView.reloadData()
        self.collectionView.layoutIfNeeded()
        var formattedTripDuration = ""
        if tripDuration > 60 {
            let hrs = Int(tripDuration / 60)
            formattedTripDuration += String(hrs) + " hr"
            if hrs > 1 { formattedTripDuration += "s " } else { formattedTripDuration += " " }
        }
        formattedTripDuration += String(Int(tripDuration) % 60)

        self.tripDurationLabel.text = formattedTripDuration + " mins"
        self.destinationArrivalTimeLabel.text = Date.dateStringFromString(dateString: destinationArrivalTime)
        if addFullLabel {
            self.busDeparturePlaceAndTimeLabel.text = ("Leaves at " + Date.dateStringFromString(dateString: busDepartureTime) + " from " + startLocation).maxLength(length: 40)
        } else {
            self.busDeparturePlaceAndTimeLabel.text = ("Leaves at " + Date.dateStringFromString(dateString: busDepartureTime)).maxLength(length: 40)
        }

        if !isLive {
            busStatusText.text = "Live"
            busStatusText.textColor = .white
        } else {
            busStatusText.text = "Scheduled"
            busStatusText.textColor = .grey2
            busStatusView.backgroundColor = .grey6
        }

        removeAnimation()
    }

How do I fix this so that the animation is the same all the time?

1

There are 1 best solutions below

1
Aman Shankar Sharma On

To animate cells when you return from a different screen you can use something like below:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    if let visibleCells = tableView.visibleCells as? [DirectionSummaryTableViewCell] {
        visibleCells.forEach {
            if let isLive = $0.isLive {
                if isLive {
                    $0.animateBusStatusBackground()
                } else {
                    $0.removeAnimation()
                }
            }
        }
    }
}