Home > Enterprise >  why table view cells generate before animation
why table view cells generate before animation

Time:11-16

I have an api that I parse and I present the data on my tableview that generates cells . I have make an animation that normally must act before as a present animation for the cells but this did not happen . the result is that the cells appear and suddenly disappear and then appear with the animation .

in the link you can find the gif that I upload the shows what happen .

https://gifyu.com/image/SEGkZ

here is the code :

The OpeningViewController is this :

import UIKit
import ViewAnimator

class OpeningViewController: UIViewController {
    
    //MARK: - IBProperties
    @IBOutlet var openingImg: UIImageView!
    @IBOutlet var startButton: UIButton!
    
    //MARK: - Properties
    var nft : Nft?
    
    //MARK:  - Life Cyrcle
    override func viewDidLoad() {
        super.viewDidLoad()
        
    }
    
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let animation = AnimationType.from(direction: .top, offset: 50)
        openingImg.animate(animations: [animation] , delay: 0.3, duration: 2)
        openingImg.layer.shadowColor = UIColor.black.cgColor
        openingImg.layer.shadowOffset = CGSize(width: 0, height: 0)
        openingImg.layer.shadowOpacity = 0.65
        openingImg.layer.shadowRadius = 10
        
    }
    
    //MARK: - Methods
    @IBAction func startApp(_ sender: Any) {
        
        HapticsManager.shared.selectionVibrate()
        let storyBoard = UIStoryboard(name: "Lobby", bundle: nil)
        let controller = storyBoard.instantiateViewController(withIdentifier: "LobbyViewController") as! LobbyViewController
        controller.modalTransitionStyle = .flipHorizontal
        self.navigationController?.pushViewController(controller, animated: true)
        
    }
}

The presentation happens in LobbyViewController :

import UIKit
import ViewAnimator

class LobbyViewController: UIViewController {
    
    // MARK: - IBProperties
    
    @IBOutlet weak var tableView: UITableView!

    // MARK: - Properties
    
    var data: [DataEnum] = []
    var likes:[Int] = []
    var numlikes: Int = 0
    var nfts: [Nft] = []
    let creators : [Creator] = []
    var icons: [Icon] = []
    var loadData = APICaller()
    
    // MARK: - Life Cyrcle
    

    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let nib = UINib(nibName: "AssetTableViewCell", bundle: nil)
        tableView.register(nib, forCellReuseIdentifier: "AssetTableViewCell")
        
        let nib2 = UINib(nibName: "CreatorsTableViewCell", bundle: nil)
        tableView.register(nib2, forCellReuseIdentifier: "CreatorsTableViewCell")
 
        tableView.dataSource = self //method to generate cells,header and footer before they are displaying
        tableView.delegate = self //method to provide information about these cells, header and footer ....
        
        downloadJSON {
            self.tableView.reloadData()
            print("success")
        }
        loadData.downloadData { (result) in
            print(result)
        }
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        let animation = AnimationType.from(direction: .top, offset: 300)
        UIView.animate(views: tableView.visibleCells,
                    animations: [animation], delay: 1, duration: 2)
    }
    
   
   
    //stelnei ta dedomena apo to kathe row ston PresentViewController 
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if let destination = segue.destination as? PresentViewController {
            if tableView.cellForRow(at: tableView.indexPathForSelectedRow!) is AssetTableViewCell {
                destination.nft = nfts[tableView.indexPathForSelectedRow!.row-1]
                destination.delegate = self
            } else {
                //add alert action
                let alert  = UIAlertController(title: "Invalid Touch", message: "You press wrong row. Choose one of the following list.", preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
                present(alert, animated: true, completion: {
                    return
                })
            }
        }
    }
    
    // MARK: - Methods

    func downloadJSON(completed: @escaping () -> ()) {
        let url = URL(string: "https://public.arx.net/~chris2/nfts.json")
        
        URLSession.shared.dataTask(with: url!) { [self] data, response, error in
            
            if error == nil {
                do {
                 
                    self.nfts = try JSONDecoder().decode([Nft].self, from: data!)
                
                    let creators = nfts.map { nft in
                        nft.creator
                    }
                    self.data.append(.type1(creators: creators))
                    
                    self.nfts.forEach { nft in
                        self.data.append(.type2(nft: nft))
                    }
                    
                    DispatchQueue.main.async {
                        completed()
                    }
                }
                catch {
                    print("error fetching data from api")
                }
            }
        }.resume()
    }
}

    // MARK: - Extensions

extension LobbyViewController : UITableViewDelegate , UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        indexPath.row == 0 ? 100 : UITableView.automaticDimension
    }
    
    //gemizo ta rows tou table
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       
        switch self.data[indexPath.item] {
        case .type1(let creators):
            print("--->", creators)
            let cell = tableView.dequeueReusableCell(withIdentifier: "CreatorsTableViewCell",
                                                                           for: indexPath) as! CreatorsTableViewCell
            cell.layer.cornerRadius = 15
            cell.layer.shadowColor = UIColor.black.cgColor
            cell.layer.shadowOffset = CGSize(width: 0, height: 0)
            cell.layer.shadowOpacity = 0.8
            cell.layer.shadowRadius = 15
            cell.layer.cornerRadius = cell.frame.height/2
            cell.updateCreators(creators)
               
            return cell
        case .type2(let nft):
            let cell = tableView.dequeueReusableCell(withIdentifier: "AssetTableViewCell",
                                                     for: indexPath) as! AssetTableViewCell
            cell.nameLabel?.text = nft.name
            cell.nameLabel.layer.cornerRadius = cell.nameLabel.frame.height/2
            cell.likesLabel?.text = "\((numlikes))"
            let imgUrl = (nft.image_url)
            print(imgUrl)
            cell.iconView.downloaded(from: imgUrl)
            cell.iconView.layer.cornerRadius = cell.iconView.frame.height/2
            return cell
        }
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        performSegue(withIdentifier: "showDetails", sender: self)
    }
}

extension LobbyViewController : TestDelegate{
    
    func sendBackTheLikess(int: Int) {
        numlikes = int
        tableView.reloadData()
    }
}

    // MARK: - Enums

enum DataEnum {
    case type1(creators: [Creator])
    case type2(nft: Nft)
}

    // MARK: - Struct

struct Constants {
    static let url = "https://public.arx.net/~chris2/nfts.json"
}

The APICaller :

import Foundation

final class APICaller {
    
    static let shared = APICaller()
    
    public struct Constants {
        static let url = "https://public.arx.net/~chris2/nfts.json"
    }
    
    public func downloadData(completion:@escaping (Result<[Nft], Error>) -> Void )
    {
        guard let url = URL(string:Constants.url)else{
            return
        }
        let task =  URLSession.shared.dataTask(with: url) { data, response, error in
            
           //print(response)
            print("here")
            guard let data = data , error == nil else{
                print("something went wrong with data")
                return
            }
            print("here4")
            //mexri edo exoume parei ta data kai tora me to do-catch tha ta kanoume convert se object
            do{
                //Decode the response
                let nfts = try JSONDecoder().decode([Nft].self, from: data)
                completion(.success(nfts))
                print(nfts)
            }catch{
                completion(.failure(error))
            }
        }
        task.resume()
    }
}

CodePudding user response:

Just move your animation from viewDidAppear(animated:) to tableView(_:willDisplay:forRowAt:) and call for each cell separately. Also don’t forget not to call this animation once it finished.

  • Related