【问题标题】:I am trying to get an UIActivityIndicatorView to show when I am loading a UITableView我正在尝试在加载 UITableView 时显示 UIActivityIndi​​catorView
【发布时间】:2019-06-15 18:33:51
【问题描述】:

这个问题已经在这个网站上回答过好几次了,我都试过了,都没有。我认为不同之处在于我的UIViewController 中有一个UITableView。我在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
        }
    }

【问题讨论】:

    标签: swift uitableview uiactivityindicatorview


    【解决方案1】:

    验证您的 Interface Builder 文件,特别是定义组件的顺序。层次结构中较高的组件可能会被它们下面定义的组件隐藏。因此,您的表格视图很可能会隐藏您的活动视图。

    您应该能够通过隐藏表格视图和其他可能位于顶部的视图来快速确认这一点。根据您的活动视图设置,您可能还需要执行tvTable.activityIndicatorView.isHidden = false。请注意,由于 UITableView 实现了内置的滚动视图,因此将活动视图作为子项添加到 UITableView 可能不是最好的方法。您最好将其定义为 tableView 的超级视图的子视图;参考:

    您对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
        }
    }
    

    【讨论】:

    • 谢谢。它仅适用于 viewDidAppear,不适用于 viewDidLoad。将其添加到情节提要中,然后使用 IBOutlet 进行所有操作可能就是秘诀。有点用,我断断续续地尝试了两个月。
    【解决方案2】:

    再次感谢, 解决方案是在我们的 TableView 下方添加一个带有 Storyboard 的 activityIndeicatorView 然后在 viewDidAppear 中有 @IBOutlet weak var mySpinner: UIActivityIndi​​catorView!

    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 秒,但在连接不佳时需要更长的时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多