Глобальный значок загрузки Swift - PullRequest
1 голос
/ 06 ноября 2019

Я делаю значок загрузки в моем файле extension.swift. Я считаю, что нам не нужно использовать какую-либо стороннюю библиотеку только для загрузки иконок. Однако я не могу хранить какие-либо значения в файле расширения. Если я не сохраню, он будет выглядеть как

import UIKit

extension UIViewController {

func startLoading() {
    let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
    activityIndicator.center = self.view.center
    activityIndicator.hidesWhenStopped = true
    activityIndicator.style = .gray
    DispatchQueue.main.async {
        self.view.addSubview(activityIndicator)
    }
    activityIndicator.startAnimating()
    UIApplication.shared.beginIgnoringInteractionEvents()
}

func stopLoading() {
    let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
    DispatchQueue.main.async {
        activityIndicator.stopAnimating()
    }
    UIApplication.shared.endIgnoringInteractionEvents()
  }
}

Так что в вашем контроллере представления вы можете напрямую вызывать startLoading () или stopLoading (). Однако stopLoading не работает. Это потому, что он не обращается к переменной, инициированной startLoading. Есть ли способы пойти по этому поводу? Большое спасибо, ребята!

Ответы [ 4 ]

2 голосов
/ 06 ноября 2019

Это можно сделать, если вы решили, что реализация находится в представлении ViewController, и у вас не всегда будет загружен индикатор активности в вашем контроллере. Но ответ @ Vollan - правильный подход к этому или использование пакета, подобного SVProgressHUD (который в основном создает UIWindow с загрузчиком в нем)

class ViewController: ActivityIndicatorController {
   override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        startLoading()    
        DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) {
            self.stopLoading()
        }
    }
}


class ActivityIndicatorController: UIViewController {
    var activityIndicator: UIActivityIndicatorView?

    func startLoading() {
        activityIndicator = UIActivityIndicatorView()
        activityIndicator?.center = self.view.center
        activityIndicator?.hidesWhenStopped = true
        activityIndicator?.style = .gray
        DispatchQueue.main.async {
            if let activityIndicator = self.activityIndicator {
               self.view.addSubview(activityIndicator)
               activityIndicator.startAnimating()
            }
        }
        UIApplication.shared.beginIgnoringInteractionEvents()
    }

    func stopLoading() {
        DispatchQueue.main.async {
            self.activityIndicator?.stopAnimating()
            self.activityIndicator?.removeFromSuperview()
            self.activityIndicator = nil
        }
        UIApplication.shared.endIgnoringInteractionEvents()
    }
}
2 голосов
/ 06 ноября 2019

Вы воссоздаете индикатор активности, поэтому он не работает.

Также у вас есть проблема перехода на новый viewController, поэтому self.view больше не будет содержать индикатор активности.

Итак, я предлагаю вам создать еще один UIWindow и положить сверху, добавить к нему индикатор вида и активности, а затем, когда вызывается stopLoading(), вы ищете этот UIWindow и удаляете все * 1009. * если он существует.

1 голос
/ 06 ноября 2019

Вы можете использовать store activityIndicator в качестве статической переменной, поэтому вы получите один и тот же объект в обоих вызовах:

extension UIViewController {

    static let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()

    func startLoading() {
        let activityIndicator = UIViewController.activityIndicator
        activityIndicator.center = self.view.center
        activityIndicator.hidesWhenStopped = true
        activityIndicator.style = .gray
        DispatchQueue.main.async {
            self.view.addSubview(activityIndicator)
        }
        activityIndicator.startAnimating()
        UIApplication.shared.beginIgnoringInteractionEvents()
    }

    func stopLoading() {
        let activityIndicator = UIViewController.activityIndicator
        DispatchQueue.main.async {
            activityIndicator.stopAnimating()
            activityIndicator.removeFromSuperview()
        }
        UIApplication.shared.endIgnoringInteractionEvents()
      }
}

Недостатком этого подхода является то, что этот activityIndicator будет храниться впамять даже ты ее скрываешь (после вызова stopLoading()).

0 голосов
/ 06 ноября 2019

Свяжите уникальный tag с вашим UIActivityIndicatorView.
В stopLoading(), используйте viewWithTag(_:), чтобы найти представление индикатора активности, и наберите stopAnimating для этого.

extension UIViewController {
    static var activityIndicatorTag = 12345

    func startLoading() {
        stopLoading()

        let activityIndicator: UIActivityIndicatorView = UIActivityIndicatorView()
        activityIndicator.tag = UIViewController.activityIndicatorTag
        activityIndicator.center = view.center
        activityIndicator.hidesWhenStopped = true
        activityIndicator.style = .gray

        DispatchQueue.main.async {
            self.view.addSubview(activityIndicator)
            activityIndicator.startAnimating()
        }
    }

    func stopLoading() {
        let activityIndicator = view.viewWithTag(UIViewController.activityIndicatorTag) as? UIActivityIndicatorView
        DispatchQueue.main.async {
            activityIndicator?.stopAnimating()
            activityIndicator?.removeFromSuperview()
        }
    }
}
...