UIRefresh 控件 endRefreshing 不起作用
Posted
技术标签:
【中文标题】UIRefresh 控件 endRefreshing 不起作用【英文标题】:UIRefresh control endRefreshing doesn't work 【发布时间】:2016-10-25 03:29:08 【问题描述】:当通过向下滑动tableview触发刷新控件时,如果没有互联网连接,则会显示一个警报,并且刷新控件预计会结束刷新,但即使在主线程中添加也不会结束刷新
class JobsForCategoryVC: UIViewController
//MARK:-Outlets
@IBOutlet weak var jobTableView: UITableView!
@IBOutlet weak var activityIndicator: UIActivityIndicatorView!
//MARK:-Properties
var refreshControl:UIRefreshControl!
var jobCategory:JobCategoryDB!
var pageNumber:Int = 1
var downloadMore:Bool = true
var jobs = [JobModel]()
//MARK:-LifeCycle
override func viewDidLoad()
super.viewDidLoad()
setupView()
freshDownload()
func setupView()
refreshControl = UIRefreshControl()
refreshControl.attributedTitle = NSAttributedString(string: "Loading fresh Jobs")
refreshControl.addTarget(self, action: #selector(self.freshDownload), for: .valueChanged)
jobTableView.addSubview(refreshControl)
func freshDownload()
pageNumber = 1
downloadMore = true
downloadJobsFrom(top: true)
func downloadJobsFrom(top:Bool)
if !refreshControl.isRefreshing && top
activityIndicator.startAnimating()
let url = URLStringList.getSearchCategoryJobString(pageNumber: pageNumber, categoryId: jobCategory.id!)
if let url = URL(string: url)
Alamofire.request(url, method: .get).responseJSON (response) in
if response.result.isSuccess
let json = response.result.value
let model = Mapper<JobModel>().mapArray(JSONArray: json as! [[String : Any]])
if model?.count == 0
self.downloadMore = false
if let jobs = model
if top
self.jobs = jobs
else
self.jobs += jobs
self.jobTableView.reloadData()
self.pageNumber += 1
self.refreshControl.endRefreshing()
self.activityIndicator.stopAnimating()
else
self.activityIndicator.stopAnimating()
DispatchQueue.main.async(execute:
self.refreshControl.endRefreshing()
self.jobTableView.reloadData()
)
if top
showInternetConnectionAlert(viewController: self, activityIndicator: self.activityIndicator, completion: nil)
extension JobsForCategoryVC:UITableViewDataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
if jobs.count > 0
jobTableView.backgroundView = nil
let cellCount = jobs.count + ((jobs.count-1)/(AdForNumberOfCells-1)) + 1
return cellCount
jobTableView.backgroundView = Bundle.main.loadNibNamed("PullToRefreshView", owner: nil, options: nil)?.first as? PullToRefreshView
return 0
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
if indexPath.row % AdForNumberOfCells == 0
if let cell = tableView.dequeueReusableCell(withIdentifier: "JobsAdTableViewCell", for: indexPath) as? JobsAdTableViewCell
cell.controller = self
return cell
else
if let cell = tableView.dequeueReusableCell(withIdentifier: "JobsTableViewCell", for: indexPath) as? JobsTableViewCell
let index = NSIndexPath(item: indexPath.row-(indexPath.row/AdForNumberOfCells)-1, section: 0)
cell.configure(job: jobs[index.row])
return cell
return UITableViewCell()
extension JobsForCategoryVC:UITableViewDelegate
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
if let webView = storyboard?.instantiateViewController(withIdentifier: "WKWebVC") as? WKWebVC
if indexPath.row % AdForNumberOfCells == 0
return
let index = NSIndexPath(item: indexPath.row-(indexPath.row/AdForNumberOfCells)-1, section: 0)
if let urlString = jobs[index.row].url
webView.url = urlString
webView.titleString = jobs[index.row].title
present(webView, animated: true, completion: nil)
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
if indexPath.row == self.jobs.count - 1 && downloadMore
downloadJobsFrom(top: false)
【问题讨论】:
【参考方案1】:这样做的简单方法是
DispatchQueue.main.async(execute:
self.jobTableView.reloadData()
self.refreshControl.endRefreshing()
self.activityIndicator.stopAnimating()
self.refreshControl.setContentOffset(CGPoint.zero, animated: true)
)
【讨论】:
这是一个很好的答案,但方法错误。看看:developer.apple.com/reference/uikit/uirefreshcontrol/… @ak2g 我相信你的意思是说self.jobTableView.setContentOffset(CGPoint.zero, animated: true)
而不是UIRefreshControl
调用setContentOffset
因为UIRefreshControl
没有这样的函数可以调用。【参考方案2】:
将UITableView contentOffset
设置为zero
在 Swift 3.0
refreshControl.endRefreshing()
self.yourTableView.contentOffset = CGPoint.zero
【讨论】:
【参考方案3】:请在主线程中添加所有 UI 程序。
成功块 => 把你的代码变成:
if let jobs = model
if top
self.jobs = jobs
else
self.jobs += jobs
self.pageNumber += 1
DispatchQueue.main.async(execute:
self.refreshControl.endRefreshing()
self.activityIndicator.stopAnimating()
self.jobTableView.reloadData()
)
还有失败块:
DispatchQueue.main.async(execute:
self.refreshControl.endRefreshing()
self.activityIndicator.stopAnimating()
self.jobTableView.reloadData()
)
无论成功还是失败,你所有的UI Progress都必须包含在主线程中。我想你忘记在Success Block中包含主线程内的UI Changes了。或者你可以这样做,
Alamofire.request(url, method: .get).responseJSON (response) in
if response.result.isSuccess
...
else
...
DispatchQueue.main.async(execute:
self.refreshControl.endRefreshing()
self.activityIndicator.stopAnimating()
self.jobTableView.reloadData()
)
看看:
RefreshControlDemo[Swift 3 Xcode 8]
【讨论】:
如果我按照你说的做,在你的 setupView() jobTableView.addSubview(refreshControl) 中删除以下代码,那么 UiRefresh 控件将不在视图层次结构中。您是在要求我删除有问题的功能,而不是解决问题。 @SamipShah,对不起,我以为你在使用 UITableViewController。我上传了示例。你可能想检查一下。不需要将 refreshControl 的 contentOffset 设置为零。请使用 Legacy Swift 版本构建此项目时选择“是”。 完成编辑。如果您看到这个演示项目,您可能会理解不需要设置 Offset = 零来隐藏 UIRefreshControl,因为它会在 endRefreshing 时自动完成。您可能需要再次检查您的代码。 developer.apple.com/reference/uikit/uirefreshcontrol/… 我已经看到了错误的原因,请看一下我编辑的答案。您必须在重新加载表之前调用 endRefreshing。如果没有,在重新加载表后,它可能会给 UIRefreshControl 带来一些错误。希望这有帮助。参考这个:***.com/questions/27280544/…【参考方案4】:我发现同样的问题
如果另一个使用 self.refresh.endRefreshing()
不起作用
我介绍这段代码 -> UIRefreshControl().endRefreshing()
替换状态为self.refresh.endRefreshing()
DispatchQueue.main.async
UIRefreshControl().endRefreshing()
self.yourTableView.contentOffset = CGPoint.zero
谢谢
【讨论】:
以上是关于UIRefresh 控件 endRefreshing 不起作用的主要内容,如果未能解决你的问题,请参考以下文章
Swift UIRefresh Control 在 UITableView 中拖动刷新会导致应用崩溃