【问题标题】:stopping activity indicator after tableView is loaded加载 tableView 后停止活动指示器
【发布时间】:2017-05-12 03:12:55
【问题描述】:

我在尝试停止活动指示器时遇到困难,应该将“self.removeLoadingScreen()”放在哪里?它在表格视图加载数据后无休止地旋转,我认为将 removeLoadingScreen() 放在 animateTable 函数下是理想的,但这是不正确的。

   var refresher: UIRefreshControl!

func showSpinnerWhileFetchingData() {
    refresher.beginRefreshing()
    myTableView.setContentOffset(CGPoint(0, myTableView.contentOffset.y - refresher.frame.size.height), animated: true)

    let qualityOfServiceClass = QOS_CLASS_BACKGROUND

    let backgroundQueue = DispatchQueue.global(Int(qualityOfServiceClass.rawValue), 0)
    backgroundQueue.async(execute: {[unowned self] in
        //fetch you data here. you are now on a background queue
        //to quick test it, uncomment the code below
        //for i in 1...2000 {
        //    self.yourArrayThatIsPopulatingTheTable.append("\(i) hot potatoes")
        //}

        DispatchQueue.main.async(execute: { () -> Void in
            self.myTableView.reloadData()
            self.refresher.endRefreshing()
        })
    })

}
func refreshData(sender: UIRefreshControl) {


    refresher.endRefreshing()
    myTableView.reloadData()

}

【问题讨论】:

    标签: ios swift uitableview uiactivityindicatorview


    【解决方案1】:

    从 setLoadingScreen 中删除这些行:

    self.spinner.startAnimating()
    self.myTableView.addSubview(loadingView)
    

    并将它们添加到 refreshData:

    func refreshData(sender: UIRefreshControl) {
    
        myTableView.addSubview(loadingView) //here 
        spinner.startAnimating() //also, start the spinner
        myTableView.reloadData()
        refreshControl.endRefreshing()
    }
    

    它应该按预期工作。 发生的情况是,在 viewDidLoad 中,当您调用 setLoadingScreen 时,您不仅设置了 loadingView,而且还将其添加到视图层次结构中(从而显示它)。

    另外,正如 Jitendra 所说,完成后不要忘记删除 loadingView。

    稍后编辑: 如果你想要的只是一个普通的 refreshControl,没有自定义,你可以摆脱大部分代码。您只需要:

    声明:

     var refresher: UIRefreshControl!
    

    在 viewDidLoad 中:

        refresher = UIRefreshControl()
        refresher.addTarget(self, action: "refreshData:", forControlEvents: .ValueChanged)
        tableView.addSubview(refresher)
    

    在刷新数据中:

      //get the new data
        refresher.endRefreshing()
        tableView.reloadData()
    

    您不需要“loadingView”、“spinner”、“loadingLabel”,也不需要“setLoadingScreen”和“removeLoadingScreen”函数。 UIRefreshControl 将为您完成所有工作。让我知道它是否有效。

    稍后编辑(Swift 2)

    如果您还想在第一次显示表格时以编程方式启动刷新控件,并在您获取数据时让它运行:

    func showSpinnerWhileFetchingData() {
        refresher.beginRefreshing()
        tableView.setContentOffset(CGPointMake(0, tableView.contentOffset.y - refresher.frame.size.height), animated: true)
    
        let qualityOfServiceClass = QOS_CLASS_BACKGROUND
        let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
        dispatch_async(backgroundQueue, {[unowned self] in
            //fetch you data here. you are now on a background queue
            //to quick test it, uncomment the code below 
            //for i in 1...2000 {
            //    self.yourArrayThatIsPopulatingTheTable.append("\(i) hot potatoes")
            //}
    
            dispatch_async(dispatch_get_main_queue(), { () -> Void in
                self.tableView.reloadData()
                self.refresher.endRefreshing()
            })
        })
    
    }
    

    在 viewWillAppear 中调用这个函数。 并且去掉 animateTable 函数,除非你真的想要逐行动画的效果,在这种情况下:

    1. 你要么让它保持原样,它就不会很明显(实际上,根本不可见......),但它会稍微减慢你的 UI

    2. 或者,如果您想花时间并且想用响应性换取特殊效果,则必须设置完成处理程序 并在上一个完成动画之后为每一行制作动画,这是另一个主题。

    希望对你有帮助:)

    EDIT 上一次编辑,翻译成 Swift 3

    func showSpinnerWhileFetchingData() {
        refresher.beginRefreshing()
    
        tableView.setContentOffset(CGPoint(x: 0, y: tableView.contentOffset.y - refresher.frame.size.height), animated: true)
    
        let qualityOfServiceClass = DispatchQoS.QoSClass.background
        let backgroundQueue = DispatchQueue.global(qos: qualityOfServiceClass)
        backgroundQueue.async(execute: {[unowned self] in
            //fetch you data here. you are now on a background queue
            //to quick test it, uncomment the code below and modify the name of the array to match the array you are using
            //for i in 1...2000 {
            //    self.yourArrayThatIsPopulatingTheTable.append("\(i) hot potatoes")
            //}
            //sleep(5)  //alternately, you can use this to test. don't forget to remove this sleep line after you test
    
            DispatchQueue.main.async(execute: { () -> Void in
                self.tableView.reloadData()
                self.refresher.endRefreshing()
            })
        })
    
    }
    

    【讨论】:

    • 你想达到什么目的?您想以哪些方式自定义您的 refreshControl?我正在尝试看看它是否更容易完成。
    • 我希望在打开视图后立即显示活动指示器,因为检索表视图数据通常需要很短的时间
    • 哦,我明白了。等等。
    • 我编辑了答案以包含您要求的内容。请参阅稍后编辑。
    • 我删除了动画表函数并尝试了您的代码,Xcode 修复了函数中的一些错误,但仍然有错误“无法使用参数列表 int 调用全局”和“参数标签与重载不匹配”在 .setContentOffSet
    【解决方案2】:

    完成后,您应该从超级视图中删除 loadingView

    所以改变你的方法:

    fileprivate func removeLoadingScreen() {
    
    self.spinner.stopAnimating()
    self.loadingLabel.isHidden = true
    //when table have data, after refreshing, remove the loadView from the table view
    loadingView.removeFromSuperView()
    }
    

    并调用此方法作为表格视图刷新完成

    func refreshData(sender: UIRefreshControl) {
    
      myTableView.reloadData()
      refreshControl.endRefreshing()
    
     //remove loading screen view now
     removeLoadingScreen()
    
    }
    

    【讨论】:

    • 我应该把新的 removeLoadingScreen() 方法放在哪里?
    • 我试过了,还是不自动停止,我下拉刷新表后才停止消失
    • 如果您只想在重新加载完成时移除微调器,那么您应该在表格视图动画的完成块中调用 removeLoadingScreen()。希望对您有所帮助。
    【解决方案3】:

    试试这个:

    fileprivate func removeLoadingScreen() {    
        self.spinner.stopAnimating() // use this two lines anywhere you need to hide indicator
        loadingView.isHidden = true
    }
    

    【讨论】:

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