Не работает анимация индикатора активности - Swift - PullRequest
0 голосов
/ 05 мая 2018

У меня есть эта проблема, когда я загружаю экран, я запускаю индикатор активности и вызываю функцию для получения данных. Сначала показывалось действие, но оно никогда не запускалось, затем я запускал каждый вызов (запускать действие и получать данные) в отдельном потоке. Анимация работала, но только один раз, когда я пытаюсь загрузить экран в другой раз, когда он снова зависает, пока данные не загружены. Это viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()

    //indicator
    indicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))
    indicator.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
    indicator.color = commons.getButtonColor()
    indicator.center = self.view.center
    indicator.hidesWhenStopped = true
    self.view.addSubview(indicator)
    DispatchQueue.main.async {
        print("We finished that.")
        // only back on the main thread, may you access UI:
        self.indicator.startAnimating()
    }


    //connect to database
    commons.ref = Database.database().reference()

    //table view
    tableV.dataSource = self
    tableV.delegate = self
    tableV.tableFooterView = UIView()
    tableV.separatorStyle = .none
    tableV.allowsSelection = false

    //change left btn
    let leftButtonItem = UIBarButtonItem.init(
        title: "",
        style: .done,
        target: self,
        action: #selector(backButtonPressed)
    )
    leftButtonItem.image = UIImage(named:"back")
    leftButtonItem.tintColor = commons.getButtonColor()
    self.navigationItem.leftBarButtonItem = leftButtonItem

    //style
    self.title = flag

    DispatchQueue.main.async {
        //get values
        if(self.flag == "Accounts"){
            self.color = "d0f0dd"
            self.getAccounts()
        }else if(self.flag == "Loans"){
            self.color = "f8ff90"
           self.getLoans()
        }else if(self.flag == "Cards"){
            self.color = "ffa669"
            self.getCards()
        }
    }

}

Снимок экрана, когда экран застрял:

enter image description here

Редактировать: функция для получения данных:

func getAccounts(){
    commons.ref.child("Accounts").observeSingleEvent(of: .value, with: { (snapshot) in
        for item in snapshot.children {
            self.values.append(item as! DataSnapshot)
        }
        self.tableV.reloadData()
        self.indicator.stopAnimating()
    }) { (error) in
        print(error.localizedDescription)
    }
}

func getCards(){
    commons.ref.child("Cards").observeSingleEvent(of: .value, with: { (snapshot) in
        self.indicator.stopAnimating()
        for item in snapshot.children {
            self.values.append(item as! DataSnapshot)
        }
        self.tableV.reloadData()
    }) { (error) in
        print(error.localizedDescription)
    }
}

func getLoans(){
    commons.ref.child("Loans").observeSingleEvent(of: .value, with: { (snapshot) in
        self.indicator.stopAnimating()
        for item in snapshot.children {
            self.values.append(item as! DataSnapshot)
        }
        self.tableV.reloadData()
    }) { (error) in
        print(error.localizedDescription)
    }
}

1 Ответ

0 голосов
/ 05 мая 2018

Во всех трех ваших функциях есть общая ошибка. Вы не вызываете stopAnimating во всех возможных ветвях вашего кода, поэтому, если обработчик завершения вызывается с error, индикатор активности будет продолжать работать.

Я не уверен, как реализованы обработчики завершения Firebase, они могут уже отправляться в основную очередь, но для полной безопасности я бы также рекомендовал отправлять вызов функции stopAnimating в основной поток, чтобы убедиться, что вы не пытайтесь случайно обновить пользовательский интерфейс из фонового потока.

func getAccounts(){
    commons.ref.child("Accounts").observeSingleEvent(of: .value, with: { (snapshot) in
        for item in snapshot.children {
            self.values.append(item as! DataSnapshot)
        }
        DispatchQueue.main.async{
            self.tableV.reloadData()
            self.indicator.stopAnimating()
        }
    }) { (error) in
        print(error.localizedDescription)
        DispatchQueue.main.async{
            self.indicator.stopAnimating()
        }
    }
}

Вы должны внести те же изменения в две другие функции.

...