Я пытаюсь получить UIActivityIndicatorView, чтобы показать, когда я загружаю UITableView - PullRequest
0 голосов
/ 15 июня 2019

Эта проблема уже была решена несколько раз на этом сайте, я пробовал их все, и ни одна из них не работает. Разница, я думаю, в том, что у меня есть UITableView внутри моего UIViewController. Я пытался при загрузке данных в viewDidLoad, здесь экран я иду из шоу, пока все не будет завершено, и появится мой новый вид. Я также пытался в viewDidAppear, здесь у меня есть пустая таблица, показывающая, прежде чем появится окончательный вид.

Я пробовал все 4 метода с этого сайта, я вызываю pauseApp(n) перед началом загрузки и restartApp(n) после завершения

    var spinner:UIActivityIndicatorView = UIActivityIndicatorView()
    var loadingView = UIView()
    var loadingLabel = UILabel()
    var indicator = UIActivityIndicatorView()
    @IBOutlet weak var tvTable: UITableView!

    func pauseApp() {
        tvTable.activityIndicatorView.startAnimating()
        tvTable.activityIndicatorView.bringSubviewToFront(aIV)
        UIApplication.shared.beginIgnoringInteractionEvents()
    }
    func pauseApp1() {
        spinner = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 20, height: 20))
        spinner.center = self.navBar.center
        spinner.hidesWhenStopped = true
        spinner.style = UIActivityIndicatorView.Style.gray
        self.navigationController?.view.addSubview(spinner)
        spinner.startAnimating()
        UIApplication.shared.beginIgnoringInteractionEvents()
    }
    func pauseApp2() {
        tvTable.activityIndicatorView.startAnimating()
        indicator.startAnimating()
        indicator.backgroundColor = UIColor.white
        UIApplication.shared.beginIgnoringInteractionEvents()
    }
    func pauseApp3() {
        setLoadingScreen()
        UIApplication.shared.beginIgnoringInteractionEvents()
    }
    func restartApp() {
    //        sleep(2)
        tvTable.activityIndicatorView.stopAnimating()
        UIApplication.shared.endIgnoringInteractionEvents()
    }
    func restartApp1() {
        spinner.stopAnimating()
        UIApplication.shared.endIgnoringInteractionEvents()
    }
    func restartApp2() {
    //        sleep(2)
        indicator.stopAnimating()
        indicator.hidesWhenStopped = true
        UIApplication.shared.endIgnoringInteractionEvents()
    }
    func restartApp3() {
    //       sleep(2)
        removeLoadingScreen()
        UIApplication.shared.endIgnoringInteractionEvents()
    }
    private func setLoadingScreen() {
        let width: CGFloat = 120
        let height: CGFloat = 30
        let x = (view.frame.width / 2) - (width / 2)
        let y = (view.frame.height / 2) - (height / 2) - 20
        loadingView.frame = CGRect(x: x, y: y, width: width, height: height)

        // Sets loading text
        loadingLabel.textColor = .gray
        loadingLabel.textAlignment = .center
        loadingLabel.text = "Loading..."
        loadingLabel.frame = CGRect(x: 0, y: 0, width: 140, height: 30)

        // Sets spinner
        spinner.style = .gray
        spinner.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
        spinner.startAnimating()

        // Adds text and spinner to the view
        loadingView.addSubview(spinner)
        loadingView.addSubview(loadingLabel)

        view.addSubview(loadingView)
        view.bringSubviewToFront(loadingView)

    }
    private func removeLoadingScreen() {
        spinner.stopAnimating()
        spinner.isHidden = true
        loadingLabel.isHidden = true
    }

    func activityIndicator()  {
        indicator = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
        indicator.style = UIActivityIndicatorView.Style.gray
        indicator.center = self.view.center
        self.view.addSubview(indicator)
    }
    fileprivate var ActivityIndicatorViewAssociativeKey = "ActivityIndicatorViewAssociativeKey"
    public var aIV: UIActivityIndicatorView = UIActivityIndicatorView()
    public extension UITableView {
        var activityIndicatorView: UIActivityIndicatorView {
            get {
                if let aIV = getAssociatedObject(&ActivityIndicatorViewAssociativeKey) as? UIActivityIndicatorView {
                return aIV
                } else {
                    let aIV = UIActivityIndicatorView(frame: CGRect(x: 0, y: 0, width: 40, height: 40))
                    aIV.style = .gray
                    aIV.color = .gray
                    aIV.backgroundColor = UIColor.black
                    aIV.center = center
                    aIV.hidesWhenStopped = true
                    addSubview(aIV)

                    setAssociatedObject(aIV, associativeKey: &ActivityIndicatorViewAssociativeKey, policy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
                   aIV.bringSubviewToFront(aIV)
                   return aIV
                }
            }

            set {
                addSubview(newValue)
                setAssociatedObject(newValue, associativeKey:&ActivityIndicatorViewAssociativeKey, policy: .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            }
        }
    }
    public extension NSObject {
        func setAssociatedObject(_ value: AnyObject?, associativeKey: UnsafeRawPointer, policy: objc_AssociationPolicy) {
            if let valueAsAnyObject = value {
                objc_setAssociatedObject(self, associativeKey, valueAsAnyObject, policy)
            }
        }

        func getAssociatedObject(_ associativeKey: UnsafeRawPointer) -> Any? {
            guard let valueAsType = objc_getAssociatedObject(self, associativeKey) else {
                return nil
            }
            return valueAsType
        }
    }

Ответы [ 2 ]

0 голосов
/ 16 июня 2019

Еще раз спасибо, Решение состоит в том, чтобы добавить ActivityIndeicatorView с Storyboard ниже нашего TableView Тогда во viewDidAppear есть @IBOutlet слабый вар mySpinner: UIActivityIndicatorView!

override func viewDidAppear(_ animated: Bool) {
    self.pauseApp()
   DispatchQueue.main.asyncAfter(deadline: .now()) {
    self.doScreen()
   }
}
func pauseApp() {
    showSpinner()
    UIApplication.shared.beginIgnoringInteractionEvents()

}

func restartApp() {
    mySpinner.stopAnimating()
    UIApplication.shared.endIgnoringInteractionEvents()
}
private func showSpinner() {
    mySpinner.startAnimating()
    mySpinner.isHidden = false
    mySpinner.hidesWhenStopped = true
}

Вызов pauseApp помещает спиннер на экран, doScreen выполняет всю работу и вызывает restartApp после его завершения. Мой doScreen выполняет большую часть работы, обращаясь к службе для получения данных, при хорошем интернет-соединении это занимает около 2 секунд, но гораздо дольше при плохом соединении.

0 голосов
/ 16 июня 2019

Проверьте файл Interface Builder, в частности, порядок, в котором определены компоненты. Компоненты, расположенные выше в иерархии, могут быть скрыты теми, которые определены ниже. Таким образом, вполне возможно, что ваш табличный вид скрывает ваш вид активности.

Вы сможете достаточно быстро это подтвердить, скрыв табличное представление и другие другие представления, которые могут быть сверху. В зависимости от настроек вида деятельности, вам также может понадобиться tvTable.activityIndicatorView.isHidden = false. Обратите внимание, что, поскольку UITableView реализует встроенное представление прокрутки, добавление представления активности в качестве дочернего к UITableView может быть не лучшим вариантом. Вам лучше определить его как дочерний элемент superview tableView; ссылка: enter image description here

Ваша попытка с pauseApp1 может работать с незначительными изменениями, но только если ваш контроллер вида находится внутри контроллера навигации. Вы также должны всегда определять любые отношения только ПОСЛЕ того, как представление добавляется как подпредставление, а не до.

Начиная новый проект с нуля, вот как вы можете отобразить индикатор активности по коду:

class ViewController: UIViewController {

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        // We add some delay for fun, absolutely not required!
        DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
            self.showSpinner()
        }
    }

    private func showSpinner() {
        let spinner = UIActivityIndicatorView.init(style: .gray)
        self.view.addSubview(spinner)
        spinner.center = self.view.center
        spinner.startAnimating()
        spinner.isHidden = false
        spinner.hidesWhenStopped = true
    }
}
...