如何仅在获取数据完成时(在 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 中仅在单元格上附加标题