【问题标题】:How to use pull to refresh in Swift?如何在 Swift 中使用 pull 刷新?
【发布时间】:2014-08-19 23:29:07
【问题描述】:

我正在使用 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()
}

我得到了:

属性 'self.refresh' 未在 super.init 调用时初始化

请帮助我了解手势识别器的行为。一个有效的示例代码会很有帮助。

谢谢。

【问题讨论】:

标签: ios swift xcode uirefreshcontrol


【解决方案1】:

错误告诉您的是,refresh 未初始化。请注意,您选择使 refresh 不是可选的,这在 Swift 中意味着它 必须 在您调用 super.init 之前有一个值(或者它被隐式调用,这似乎是您的情况)。要么将refresh 设为可选(可能是你想要的),要么以某种方式对其进行初始化。

我建议再次阅读 Swift 介绍性文档,该文档详细介绍了这一点。

最后一件事,不是答案的一部分,正如@Anil 指出的那样,iOS 中有一个内置的拉动刷新控件,称为UIRefresControl,这可能值得研究。

【讨论】:

    【解决方案2】:

    拉动刷新内置于 iOS 中。你可以像这样快速地做到这一点

    let refreshControl = UIRefreshControl()
    
    override func viewDidLoad() {
       super.viewDidLoad()
    
       refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
       refreshControl.addTarget(self, action: #selector(self.refresh(_:)), for: .valueChanged)
       tableView.addSubview(refreshControl) // not required when using UITableViewController
    }
    
    @objc func refresh(_ sender: AnyObject) {
       // Code to refresh table view  
    }
    

    在某些时候你可能会结束刷新。

    refreshControl.endRefreshing()
    

    【讨论】:

    • 谢谢!我用过这个。只是一些调整,用于延迟加载。我会这样做:“lazy var refreshControl = UIRefreshControl()”我发现避免强制解包变量是一种很好的做法,因为它感觉就像破坏了语言安全性。
    • 只是一个简短的说明,您甚至不需要将 refreshControl 添加到 tableview。这是隐式处理的。
    • @KendrickLedet 即使您不使用 UITableViewController?
    • 我怎样才能在tableview的顶部和底部使用这个解决方案?
    • Swift 4 更新:refreshControl.addTarget(self, action: "refresh:", for: .valueChanged)
    【解决方案3】:

    故事板和 Swift 的解决方案:

    1. 打开您的 .storyboard 文件,在情节提要中选择一个 TableViewController 并“启用”表格视图控制器:实用程序中的刷新功能。

    2. 打开关联的UITableViewController 类并将以下Swift 5 行添加到viewDidLoad 方法中。

      self.refreshControl?.addTarget(self, action: #selector(refresh), for: UIControl.Event.valueChanged)
      
    3. 在viewDidLoad方法上方添加如下方法

      func refresh(sender:AnyObject)
      {
          // Updating your data here...
      
          self.tableView.reloadData()
          self.refreshControl?.endRefreshing()
      }
      

    【讨论】:

    • 另外,您可以通过从 Storyboard 中的 Refresh Control 拖动到您的 ViewController 来使用 Storyboard 添加刷新操作
    • 如果我的加载数据是异步的,我应该在回调中put self.tableView.reloadData()self.refreshControl?.endRefreshing()吗?
    • 没错!并将reloadData() 放入主队列以立即刷新您的 UI:dispatch_async(dispatch_get_main_queue(),{ self.tableView.reloadData() });
    • 这种方式比公认的答案更受欢迎,因为没有布局错误(至少对我来说使用 swift 2+)
    • 这个答案应该是得票最多的正确答案
    【解决方案4】:

    我构建了一个 RSS 提要应用程序,其中我有一个 Pull To refresh 功能,该功能最初存在上面列出的一些问题。

    但是要添加到上面的用户答案,我到处寻找我的用例,但找不到。我正在从网络 (RSSFeed) 下载数据,我想下拉我的故事的 tableView 以刷新。

    上面提到的内容涵盖了正确的领域,但人们遇到了一些问题,这就是我所做的,它很有效:

    我采用@Blankarsch 的方法并转到我的 main.storyboard 并选择要使用刷新的表格视图,然后没有提到的是创建 IBOutlet 和 IBAction 以有效地使用刷新

    //Created from main.storyboard cntrl+drag refresh from left scene to assistant editor
    @IBOutlet weak var refreshButton: UIRefreshControl
    
    override func viewDidLoad() {
      ...... 
      ......
      //Include your code
      ......
      ......
      //Is the function called below, make sure to put this in your viewDidLoad 
      //method or not data will be visible when running the app
      getFeedData()
    }
    
    //Function the gets my data/parse my data from the web (if you havnt already put this in a similar function)
    //remembering it returns nothing, hence return type is "-> Void"
    func getFeedData() -> Void{
      .....
      .....
    }
    
    //From main.storyboard cntrl+drag to assistant editor and this time create an action instead of outlet and 
    //make sure arguments are set to none and note sender
    @IBAction func refresh() {
      //getting our data by calling the function which gets our data/parse our data
      getFeedData()
    
      //note: refreshControl doesnt need to be declared it is already initailized. Got to love xcode
      refreshControl?.endRefreshing()
    }

    希望对和我有同样情况的人有所帮助

    【讨论】:

      【解决方案5】:

      Swift 中使用这个,

      如果你想在 WebView 中拉动刷新,

      所以试试这个代码:

      override func viewDidLoad() {
          super.viewDidLoad()
          addPullToRefreshToWebView()
      }
      
      func addPullToRefreshToWebView(){
          var refreshController:UIRefreshControl = UIRefreshControl()
      
          refreshController.bounds = CGRectMake(0, 50, refreshController.bounds.size.width, refreshController.bounds.size.height) // Change position of refresh view
          refreshController.addTarget(self, action: Selector("refreshWebView:"), forControlEvents: UIControlEvents.ValueChanged)
          refreshController.attributedTitle = NSAttributedString(string: "Pull down to refresh...")
          YourWebView.scrollView.addSubview(refreshController)
      
      }
      
      func refreshWebView(refresh:UIRefreshControl){
          YourWebView.reload()
          refresh.endRefreshing()
      }
      

      【讨论】:

        【解决方案6】:

        你可以使用 tableView 的这个子类:

        import UIKit
        
        protocol PullToRefreshTableViewDelegate : class {
            func tableViewDidStartRefreshing(tableView: PullToRefreshTableView)
        }
        
        class PullToRefreshTableView: UITableView {
        
            @IBOutlet weak var pullToRefreshDelegate: AnyObject?
            private var refreshControl: UIRefreshControl!
            private var isFirstLoad = true
        
            override func willMoveToSuperview(newSuperview: UIView?) {
                super.willMoveToSuperview(newSuperview)
        
                if (isFirstLoad) {
                    addRefreshControl()
                    isFirstLoad = false
                }
            }
        
            private func addRefreshControl() {
                refreshControl = UIRefreshControl()
                refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
                refreshControl.addTarget(self, action: "refresh", forControlEvents: .ValueChanged)
                self.addSubview(refreshControl)
            }
        
            @objc private func refresh() {
               (pullToRefreshDelegate as? PullToRefreshTableViewDelegate)?.tableViewDidStartRefreshing(self)
            }
        
            func endRefreshing() {
                refreshControl.endRefreshing()
            }
        
        }
        

        1 - 在界面生成器中,将 tableView 的类更改为 PullToRefreshTableView 或以编程方式创建 PullToRefreshTableView

        2 - 在您的视图控制器中实现PullToRefreshTableViewDelegate

        3 - 当表格视图开始刷新时,tableViewDidStartRefreshing(tableView: PullToRefreshTableView) 将在您的视图控制器中调用

        4 - 调用yourTableView.endRefreshing()完成刷新

        【讨论】:

          【解决方案7】:

          我建议做一个 pull To Refresh 的扩展以在每个类中使用。

          1) 制作一个空的 swift 文件:文件 - 新建 - 文件 - Swift 文件。

          2) 添加以下内容

              //  AppExtensions.swift
          
              import Foundation
              import UIKit    
          
              var tableRefreshControl:UIRefreshControl = UIRefreshControl()    
          
              //MARK:- VIEWCONTROLLER EXTENSION METHODS
              public extension UIViewController
              {
                  func makePullToRefreshToTableView(tableName: UITableView,triggerToMethodName: String){
          
                      tableRefreshControl.attributedTitle = NSAttributedString(string: "TEST: Pull to refresh")
                      tableRefreshControl.backgroundColor = UIColor.whiteColor()
                      tableRefreshControl.addTarget(self, action: Selector(triggerToMethodName), forControlEvents: UIControlEvents.ValueChanged)
                      tableName.addSubview(tableRefreshControl)
                  }
                  func makePullToRefreshEndRefreshing (tableName: String)
                  {
                      tableRefreshControl.endRefreshing()
          //additional codes
          
                  }
              }    
          

          3) 在您的视图控制器中调用这些方法:

            override func viewWillAppear(animated: Bool) {
          
          self.makePullToRefreshToTableView(bidderListTable, triggerToMethodName: "pullToRefreshBidderTable")
          }
          

          4) 在某些时候你想结束刷新:

            func pullToRefreshBidderTable() {
          self.makePullToRefreshEndRefreshing("bidderListTable")    
          //Code What to do here.
          }
          OR    
          self.makePullToRefreshEndRefreshing("bidderListTable")
          

          【讨论】:

          • 您的代码带有项目名称和版权声明,可能对您不利:) 。您在此处发布的任何代码都应该免费供所有人使用
          • 谢谢阿尼尔!我确实忘记删除那些。
          【解决方案8】:

          这就是我使用 Xcode 7.2 使其工作的方式,我认为这是一个主要错误。我在我的UITableViewController 里面使用它在我的viewWillAppear 里面

          refreshControl = UIRefreshControl()
          refreshControl!.addTarget(self, action: "configureMessages", forControlEvents: .ValueChanged)
          refreshControl!.beginRefreshing()
          
          configureMessages()
          
          func configureMessages() {
              // configuring messages logic here
          
              self.refreshControl!.endRefreshing()
          }
          

          如您所见,我必须在设置UIRefreshControl 后调用configureMessage() 方法,然后再进行后续刷新。

          【讨论】:

            【解决方案9】:

            Anhil 的回答对我帮助很大。

            但是,在进一步试验后,我注意到建议的解决方案有时会导致不那么漂亮的UI glitch

            相反,选择this approach* 对我有用。

            *斯威夫特 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
            

            【讨论】:

              【解决方案10】:

              其他答案是正确的,但要了解更多详情,请查看此帖子Pull to Refresh

              在情节提要中启用刷新

              当您使用 UITableViewController 时,解决方案相当简单:首先,在情节提要中选择表格视图控制器,打开属性检查器,然后启用刷新:

              UITableViewController 配备了对 UIRefreshControl 的引用。当用户下拉时,您只需要连接一些东西来启动和完成刷新。

              覆盖 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)
              }
              
              1. 由于我已将“handleRefresh:”(注意冒号!)指定为 action 参数,我需要在此定义一个函数 UITableViewController 类同名。此外, 函数应该接受一个参数
              2. 我们希望为调用的 UIControlEvent 调用此操作 价值改变
              3. 别忘了致电refreshControl.endRefreshing()

              欲了解更多信息,请提及链接,所有功劳归于该帖子

              【讨论】:

              • 虽然理论上这可以回答这个问题,it would be preferable 在这里包含答案的基本部分,并提供链接以供参考。
              【解决方案11】:

              斯威夫特 4

              var refreshControl: UIRefreshControl!
              
              override func viewDidLoad() {
                  super.viewDidLoad()
              
                  refreshControl = UIRefreshControl()
                  refreshControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
                  refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged)
                  tableView.addSubview(refreshControl) 
              }
              
              @objc func refresh(_ sender: Any) {
                  //  your code to reload tableView
              }
              

              你可以停止刷新:

              refreshControl.endRefreshing()
              

              【讨论】:

              • 别忘了在你的例子中提到tableView.reloadData()
              • 嗨,我通过这种方式创建了我的刷新控件:var refControl: UIRefreshControl{ let rfControl = UIRefreshControl() rfControl.attributedTitle = NSAttributedString(string: "") rfControl.tintColor = UIColor(red:0.16, green:0.68, blue:0.9, alpha:1) rfControl.addTarget(self, action: #selector(getNewMessageList), for: .valueChanged) return rfControl }。然后调用endRefreshing(),它不起作用(刷新控件仍然显示在那里),但是按照你的方式,它起作用了,请告诉我为什么?
              • @lee 因为 rfControl 是本地的,无法从外部访问。尝试将 rfControl 初始化为 VC 的全局变量:var rfControl = UIRefreshControl(),并使用 rfControl.endRefreshing() 停止
              • 一个问题:.valueChanged事件是在哪里触发的?我不明白这种联系。
              • 触发UIRefreshControl的时候,你addTarget的时候看到的:refreshControl.addTarget(self, action: #selector(self.refresh), for: UIControlEvents.valueChanged)
              【解决方案12】:

              我想提一下自 iOS 10 以来已包含的 PRETTY COOL 功能,即:

              目前,UIRefreshControlUICollectionViewUITableViewUIScrollView 中均直接支持!

              每个视图都有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
              }
              
              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)
              }
              

              【讨论】:

              • 嘿伙计,我在 doSomething 函数中叫什么?如果我调用 reload.Data 它不想再次加载!
              • @JavierV。在doSomething 函数中添加一个断点,如果它可以访问,那么你必须检查你的代码。
              • doSomething 应该是@objc func
              【解决方案13】:

              我正在使用拉动刷新

              DGElasticPullToRefresh

              https://github.com/gontovnik/DGElasticPullToRefresh

              安装

              pod 'DGElasticPullToRefresh'

              import DGElasticPullToRefresh
              

              并将此函数放入您的 swift 文件并从您的

              中调用此函数

              覆盖 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()
              
               }
              

              它看起来像

              编码愉快:)

              【讨论】:

                【解决方案14】:
                func pullToRefresh(){
                
                    let refresh = UIRefreshControl()
                    refresh.addTarget(self, action: #selector(handleTopRefresh(_:)), for: .valueChanged )
                    refresh.tintColor = UIColor.appBlack
                    self.tblAddressBook.addSubview(refresh)
                
                }
                @objc func handleTopRefresh(_ sender:UIRefreshControl){
                    self.callAddressBookListApi(isLoaderRequired: false)
                    sender.endRefreshing()
                }
                

                【讨论】:

                  【解决方案15】:

                  详情

                  • Xcode 版本 10.3 (10G8),Swift 5

                  特点

                  • 能够以编程方式进行“拉动刷新”
                  • 防止多重“拉动刷新”事件
                  • 能够在视图控制器切换时继续为活动指示器设置动画(例如,在 TabController 的情况下)

                  解决方案

                  import UIKit
                  
                  class RefreshControl: UIRefreshControl {
                  
                      private weak var actionTarget: AnyObject?
                      private var actionSelector: Selector?
                      override init() { super.init() }
                  
                      convenience init(actionTarget: AnyObject?, actionSelector: Selector) {
                          self.init()
                          self.actionTarget = actionTarget
                          self.actionSelector = actionSelector
                          addTarget()
                      }
                  
                      private func addTarget() {
                          guard let actionTarget = actionTarget, let actionSelector = actionSelector else { return }
                          addTarget(actionTarget, action: actionSelector, for: .valueChanged)
                      }
                  
                      required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) }
                  
                      func endRefreshing(deadline: DispatchTime? = nil) {
                          guard let deadline = deadline else { endRefreshing(); return }
                          DispatchQueue.global(qos: .default).asyncAfter(deadline: deadline) { [weak self] in
                              DispatchQueue.main.async { self?.endRefreshing() }
                          }
                      }
                  
                      func refreshActivityIndicatorView() {
                          guard let selector = actionSelector else { return }
                          let _isRefreshing = isRefreshing
                          removeTarget(actionTarget, action: selector, for: .valueChanged)
                          endRefreshing()
                          if _isRefreshing { beginRefreshing() }
                          addTarget()
                      }
                  
                      func generateRefreshEvent() {
                          beginRefreshing()
                          sendActions(for: .valueChanged)
                      }
                  }
                  
                  public extension UIScrollView {
                  
                      private var _refreshControl: RefreshControl? { return refreshControl as? RefreshControl }
                  
                      func addRefreshControll(actionTarget: AnyObject?, action: Selector, replaceIfExist: Bool = false) {
                          if !replaceIfExist && refreshControl != nil { return }
                          refreshControl = RefreshControl(actionTarget: actionTarget, actionSelector: action)
                      }
                  
                      func scrollToTopAndShowRunningRefreshControl(changeContentOffsetWithAnimation: Bool = false) {
                          _refreshControl?.refreshActivityIndicatorView()
                          guard   let refreshControl = refreshControl,
                                  contentOffset.y != -refreshControl.frame.height else { return }
                          setContentOffset(CGPoint(x: 0, y: -refreshControl.frame.height), animated: changeContentOffsetWithAnimation)
                      }
                  
                      private var canStartRefreshing: Bool {
                          guard let refreshControl = refreshControl, !refreshControl.isRefreshing else { return false }
                          return true
                      }
                  
                      func startRefreshing() {
                          guard canStartRefreshing else { return }
                          _refreshControl?.generateRefreshEvent()
                      }
                  
                      func pullAndRefresh() {
                          guard canStartRefreshing else { return }
                          scrollToTopAndShowRunningRefreshControl(changeContentOffsetWithAnimation: true)
                          _refreshControl?.generateRefreshEvent()
                      }
                  
                      func endRefreshing(deadline: DispatchTime? = nil) { _refreshControl?.endRefreshing(deadline: deadline) }
                  }
                  

                  用法

                  // Add refresh control to UICollectionView / UITableView / UIScrollView
                  private func setupTableView() {
                      let tableView = UITableView()
                      // ...
                      tableView.addRefreshControll(actionTarget: self, action: #selector(refreshData))
                  }
                  
                  @objc func refreshData(_ refreshControl: UIRefreshControl) {
                      tableView?.endRefreshing(deadline: .now() + .seconds(3))
                  }
                  
                  // Stop refreshing in UICollectionView / UITableView / UIScrollView
                  tableView.endRefreshing()
                  
                  // Simulate pull to refresh in UICollectionView / UITableView / UIScrollView
                  tableView.pullAndRefresh()
                  

                  完整样本

                  不要忘记在此处添加解决方案代码

                  import UIKit
                  
                  class ViewController: UIViewController {
                  
                      private weak var tableView: UITableView?
                  
                      override func viewDidLoad() {
                          super.viewDidLoad()
                          setupTableView()
                      }
                  
                      private func setupTableView() {
                          let tableView = UITableView()
                          view.addSubview(tableView)
                          tableView.translatesAutoresizingMaskIntoConstraints = false
                          tableView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
                          tableView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
                          tableView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
                          tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
                          tableView.dataSource = self
                          tableView.delegate = self
                          tableView.addRefreshControll(actionTarget: self, action: #selector(refreshData))
                          self.tableView = tableView
                      }
                  }
                  
                  extension ViewController {
                      @objc func refreshData(_ refreshControl: UIRefreshControl) {
                          print("refreshing")
                          tableView?.endRefreshing(deadline: .now() + .seconds(3))
                      }
                  }
                  
                  extension ViewController: UITableViewDataSource {
                      func numberOfSections(in tableView: UITableView) -> Int { return 1 }
                      func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return 20 }
                      func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
                          let cell = UITableViewCell()
                          cell.textLabel?.text = "\(indexPath)"
                          return cell
                      }
                  }
                  
                  extension ViewController: UITableViewDelegate {
                      func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
                          tableView.pullAndRefresh()
                      }
                  }
                  

                  【讨论】:

                  • 谢谢@Vasily。我认为,这是互联网上最好的答案和解决方案。
                  【解决方案16】:

                  您可以通过使用几行代码来实现这一点。那么为什么你要卡在第三方库或 UI 中。 拉动刷新是在 iOS 中内置的。你可以像这样快速地做到这一点

                  var pullControl = UIRefreshControl()
                  
                  override func viewDidLoad() {
                     super.viewDidLoad()
                  
                     pullControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
                     pullControl.addTarget(self, action: #selector(pulledRefreshControl(_:)), for: UIControl.Event.valueChanged)
                     tableView.addSubview(pullControl) // not required when using UITableViewController
                  }
                  
                  @objc func pulledRefreshControl(sender:AnyObject) {
                     // Code to refresh table view  
                  }
                  
                  

                  【讨论】:

                    【解决方案17】:

                    斯威夫特 5

                    private var pullControl = UIRefreshControl()
                    
                    pullControl.attributedTitle = NSAttributedString(string: "Pull to refresh")
                            pullControl.addTarget(self, action: #selector(refreshListData(_:)), for: .valueChanged)
                            if #available(iOS 10.0, *) {
                                tableView.refreshControl = pullControl
                            } else {
                                tableView.addSubview(pullControl)
                            }
                    // Actions
                    @objc private func refreshListData(_ sender: Any) {
                            self.pullControl.endRefreshing() // You can stop after API Call
                            // Call API
                        }
                    

                    【讨论】:

                      【解决方案18】:

                      由于较少的可定制性、代码重复和下拉刷新控件带来的错误,我创建了一个库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 子类(即 UITableView/UICollectionView)之后添加神奇的关键字 ptr

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

                      【讨论】:

                        猜你喜欢
                        • 2021-12-25
                        • 2014-10-09
                        • 1970-01-01
                        • 1970-01-01
                        • 2015-11-06
                        • 2016-12-26
                        • 2023-04-07
                        • 2018-02-15
                        • 1970-01-01
                        相关资源
                        最近更新 更多