我正在使用swift构建一个RSS阅读器,需要实现重新加载功能。

以下是我如何努力做到这一点。

class FirstViewController: UIViewController,
    UITableViewDelegate, UITableViewDataSource {

   @IBOutlet var refresh: UIScreenEdgePanGestureRecognizer
   @IBOutlet var newsCollect: UITableView

   var activityIndicator:UIActivityIndicatorView? = nil

   override func viewDidLoad() {
       super.viewDidLoad()
       self.newsCollect.scrollEnabled = true
      // Do any additional setup after loading the view, typically from a nib.

      if nCollect.news.count <= 2{
          self.collectNews()
       }
      else{
          self.removeActivityIndicator()
       }
      view.addGestureRecognizer(refresh)
   }



@IBAction func reload(sender: UIScreenEdgePanGestureRecognizer) {
    nCollect.news = News[]()
    return newsCollect.reloadData()
}

我得到:

财产的自我。刷新'未在super初始化。init调用

请帮助我理解手势识别器的行为。一个工作样例代码将是一个很大的帮助。

谢谢。


当前回答

UIRefreshControl直接支持在每个UICollectionView, UITableView和UIScrollView(需要iOS 10+)!

这些视图中的每一个都有一个refreshControl实例属性,这意味着不再需要在你的滚动视图中添加它作为子视图,你所要做的就是:

@IBOutlet weak var collectionView: UICollectionView!

override func viewDidLoad() {
    super.viewDidLoad()
    
    let refreshControl = UIRefreshControl()
    refreshControl.addTarget(self, action: #selector(doSomething), for: .valueChanged)
    
    // this is the replacement of implementing: "collectionView.addSubview(refreshControl)"
    collectionView.refreshControl = refreshControl
}

@objc func doSomething(refreshControl: UIRefreshControl) {
    print("Hello World!")
    
    // somewhere in your code you might need to call:
    refreshControl.endRefreshing()
}

就我个人而言,我觉得将它作为滚动视图的属性比将它作为子视图添加更自然,特别是因为唯一合适的视图作为UIRefreshControl的父视图是一个滚动视图,即使用UIRefreshControl的功能只在与滚动视图一起工作时有用;这就是为什么这种方法应该更明显地设置刷新控件视图。

但是,你仍然可以选择基于iOS版本使用addSubview:

if #available(iOS 10.0, *) {
  collectionView.refreshControl = refreshControl
} else {
  collectionView.addSubview(refreshControl)
}

其他回答

对于拉刷新,我正在使用

DGElasticPullToRefresh

https://github.com/gontovnik/DGElasticPullToRefresh

安装

豆荚的DGElasticPullToRefresh

import DGElasticPullToRefresh

然后把这个函数放到你的swift文件中,然后从你的

override func viewWillAppear(_ animated: Bool)

     func Refresher() {
      let loadingView = DGElasticPullToRefreshLoadingViewCircle()
      loadingView.tintColor = UIColor(red: 255.0/255.0, green: 255.0/255.0, blue: 255.0/255.0, alpha: 1.0)
      self.table.dg_addPullToRefreshWithActionHandler({ [weak self] () -> Void in

          //Completion block you can perfrom your code here.

           print("Stack Overflow")

           self?.table.dg_stopLoading()
           }, loadingView: loadingView)
      self.table.dg_setPullToRefreshFillColor(UIColor(red: 255.0/255.0, green: 57.0/255.0, blue: 66.0/255.0, alpha: 1))
      self.table.dg_setPullToRefreshBackgroundColor(self.table.backgroundColor!)
 }

不要忘记在视图消失时删除引用

要删除拉刷新,请将此代码放入您的

重写func viewDidDisappear(_ animated: Bool)

override func viewDidDisappear(_ animated: Bool) {
      table.dg_removePullToRefresh()

 }

看起来就像

快乐编码:)

由于可定制性较差,代码重复和刷新控件带来的错误,我创建了一个库PullToRefreshDSL,它使用DSL模式,就像SnapKit一样

// You only have to add the callback, rest is taken care of
tableView.ptr.headerCallback = { [weak self] in // weakify self to avoid strong reference
    DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) { // your network call
        self?.tableView.ptr.isLoadingHeader = false // setting false will hide the view
    }
}

你只需要在任何UIScrollView子类后添加神奇的关键字ptr,即UITableView/UICollectionView

你不需要下载库,你可以探索和修改源代码,我只是指向一个可能的实现拉动刷新iOS

其他答案是正确的,但更多细节请查看这篇文章拉到刷新

在故事板中启用刷新

当你使用UITableViewController时,解决方案相当简单:首先,在你的故事板中选择表视图控制器,打开属性检查器,并启用刷新:

UITableViewController自带一个UIRefreshControl的引用。您只需要连接一些东西,以便在用户下拉时启动和完成刷新。

Override viewDidLoad()

在你重写viewDidLoad()时,添加一个目标来处理刷新,如下所示:

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
        
    self.refreshControl?.addTarget(self, action: "handleRefresh:", forControlEvents: UIControlEvents.ValueChanged)
}

因为我指定了“handleRefresh:”(注意冒号!)作为 action参数,我需要在这里定义一个函数 UITableViewController类的同名。此外, 函数应该有一个参数 我们希望这个动作在UIControlEvent被调用时被调用 ValueChanged 别忘了调用refreshControl.endRefreshing()

要了解更多信息,请去提到链接,所有的功劳都归于那个帖子

使用storyboard和Swift的解决方案:

Open your .storyboard file, select a TableViewController in your storyboard and "Enable" the Table View Controller: Refreshing feature in the Utilities. Open the associated UITableViewController class and add the following Swift 5 line into the viewDidLoad method. self.refreshControl?.addTarget(self, action: #selector(refresh), for: UIControl.Event.valueChanged) Add the following method above the viewDidLoad method func refresh(sender:AnyObject) { // Updating your data here... self.tableView.reloadData() self.refreshControl?.endRefreshing() }

Anhil的回答对我帮助很大。

然而,在进一步试验之后,我注意到建议的解决方案有时会导致不那么漂亮的UI故障。

相反,采用这种方法*让我成功了。

*迅速2.1

//Create an instance of a UITableViewController. This will host your UITableView.
private let tableViewController = UITableViewController()

//Add tableViewController as a childViewController and set its tableView property to your UITableView.
self.addChildViewController(self.tableViewController)
self.tableViewController.tableView = self.tableView
self.refreshControl.addTarget(self, action: "refreshData:", forControlEvents: .ValueChanged)
self.tableViewController.refreshControl = self.refreshControl