如何仅在获取数据完成时(在 Swift 中)隐藏我的 UIRefreshControl?

Posted

技术标签:

【中文标题】如何仅在获取数据完成时(在 Swift 中)隐藏我的 UIRefreshControl?【英文标题】:How can I hide my UIRefreshControl only when fetching data is complete (in Swift)? 【发布时间】:2016-03-20 13:09:05 【问题描述】:

我有一个 UITableView,最近我添加了一个拉动刷新功能。

到目前为止,代码如下所示:

@IBOutlet var tview: UITableView!
var currentDate: NSDate = NSDate()

override func viewDidLoad()

    let refreshControl = UIRefreshControl()

    refreshControl.addTarget(self, action: "refresh:", forControlEvents: .ValueChanged)
    refreshControl.attributedTitle = NSAttributedString(string: "last updated on \(currentDate)")


    tview.separatorStyle = UITableViewCellSeparatorStyle.None
    tview.addSubview(refreshControl)


func refresh(refreshControl: UIRefreshControl) 

    refreshControl.attributedTitle = NSAttributedString(string: "last updated on \(currentDate)")

    fetchRequests()


如您所见,我在刷新控制函数中调用了一个函数fetchRequests(),我还在此处设置了属性标题以向用户显示上次更新的时间。

我的函数fetchRequests() 调用一个网络服务并异步获取数据:

func fetchRequests()
    Alamofire.request(.GET, "https://mywebservice", parameters: ["username": username])
        .responseJSON  response in
            switch response.result 
            case .Success:

                self.items.removeAllObjects()
                if let jsonData = response.result.value as? [[String: AnyObject]] 
                    for requestJSON in jsonData 
                        if let request = SingleRequest.fromJSON(JSON(requestJSON))
                            self.items.addObject(request)
                            dispatch_async(dispatch_get_main_queue(),
                                self.tview.reloadData()
                                self.refreshControl?.endRefreshing()
                                self.currentDate = NSDate()
                            )

                        
                    
                
                //self.tview.reloadData()

            case .Failure(let error):
                print("SWITCH ERROR")
                print(error)
            

    
  

我想在刷新完成后隐藏 refreshControl。

这一行:

self.refreshControl?.endRefreshing()

在 fetchRecords 中 success 的情况下不起作用。如何从那里引用 refreshControl 并在成功的情况下结束它?另外,目前我在 fetchRecords 的最后注释掉了这一行:

//self.tview.reloadData()

因为我相信/希望重新加载发生在 dispatch_async 内部 - 这是一个好的假设吗?

【问题讨论】:

【参考方案1】:

您在这里做错的是您的 refreshControl 对象是本地的,并且仅在 viewDidLoad 中可用,因此即使您在 fetchRequest() 中使用它也不起作用。将您的 refreshControl 对象传递给 fetchRequests 函数。试试下面的东西:

func refresh(refreshControl: UIRefreshControl) 
refreshControl.attributedTitle = NSAttributedString(string: "last updated on \(currentDate)")
fetchRequests(refreshControl)


func fetchRequest(refreshControl: UIRefreshControl) 
  //existing code....
     dispatch_async(dispatch_get_main_queue(),
                            self.tview.reloadData()
                            refreshControl?.endRefreshing()
                            self.currentDate = NSDate()
                        )

如果你在 func refresh(refreshControl: UIRefreshControl) 中移动你的 enter fetchRequests func 也可以。

【讨论】:

谢谢,但我在这里刚刚意识到两件事 - 第一个:self.tview.reloadData() 运行多次,因为它在循环中,并且在每条记录刷新表后刷新与获取的记录一样多视图,所以我不能在那里结束刷新,因为它会被调用 xx 次,我应该在循环完成后只执行一次 endRefreshing - 我该如何实现? 另一件事是我在本地创建它,因为 UITableViewController 中已经有一个 refreshControl 并且我的类继承了它:class UserList: UITableViewController 所以我不知道如何使用该类中的刷新控制器。 .. 将调度块移到for循环之外和之后,看看它是否工作。这里的 SingleRequest 是干什么用的,是另一个服务调用吗? 不,它只是创建一个结构以供将来使用,没有更多的服务调用:)【参考方案2】:

当服务在后台线程上调用时,您无法刷新 UI。当您收到响应时,请在 dispatch_get_main_queue 中进行解析和 Userinteface 更改。

func fetchRequests()
    Alamofire.request(.GET, "https://mywebservice", parameters: ["username": username])
        .responseJSON  response in
dispatch_async(dispatch_get_main_queue(),
            switch response.result 
            case .Success:

                self.items.removeAllObjects()
                if let jsonData = response.result.value as? [[String: AnyObject]] 
                    for requestJSON in jsonData 
                        if let request = SingleRequest.fromJSON(JSON(requestJSON))
                            self.items.addObject(request)

                                self.tview.reloadData()
                                self.refreshControl?.endRefreshing()
                                self.currentDate = NSDate()


                        
                    
                
                //self.tview.reloadData()

            case .Failure(let error):
                print("SWITCH ERROR")
                print(error)
            

    
)
  

【讨论】:

但这不是我现在在`dispatch_async(dispatch_get_main_queue(),` 中调用self.refreshControl?.endRefreshing() 时正在做的事情吗?因为如果是这样,那么不幸的是它不起作用......

以上是关于如何仅在获取数据完成时(在 Swift 中)隐藏我的 UIRefreshControl?的主要内容,如果未能解决你的问题,请参考以下文章

从 api 获取所有数据以及如何在 swift ios 中仅在单元格上附加标题

仅在完成操作IOS Swift 3后才使用户访问视图[关闭]

Swift - 如何隐藏未知按钮?

Swift仅在启用位置服务时执行代码

仅在执行任务时隐藏 UIBarButtonItem

一个 UIView Swift 中的多个 TableViews - 如何同时显示