Wie verwende ich Pull, um in Swift zu aktualisieren?

247

Ich baue einen RSS-Reader mit Swift und muss Pull implementieren, um die Funktionalität neu zu laden.

Hier ist, wie ich es versuche.

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

Ich bekomme :

Die Eigenschaft 'self.refresh' wurde beim Aufruf von super.init nicht initialisiert

Bitte helfen Sie mir, das Verhalten von Gestenerkennern zu verstehen. Ein funktionierender Beispielcode ist eine große Hilfe.

Vielen Dank.

xrage
quelle
Sie möchten ziehen, um in der Tabellenansicht etwas wie techrepublic.com/blog/software-engineer/… zu aktualisieren
Anil Varghese
Ja, ich brauche nur diese Funktionalität, aber ich habe keine Ahnung von ObjC. Möchten Sie schnell implementieren.
Xrage

Antworten:

590

Pull to Refresh ist in iOS integriert. Sie könnten dies schnell tun

var 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  
}

Irgendwann könnten Sie die Aktualisierung beenden.

refreshControl.endRefreshing()
Anil Varghese
quelle
15
Vielen Dank! Ich habe das benutzt. Nur ein paar Optimierungen zum faulen Laden. Ich würde tun: "lazy var refreshControl = UIRefreshControl ()" Ich finde es eine gute Praxis, das erzwungene Auspacken von Variablen zu vermeiden, da es sich so anfühlt, als würde es die Sprachsicherheit beeinträchtigen.
nmdias
10
Nur eine kurze Anmerkung, Sie müssen nicht einmal das refreshControl zur Tabellenansicht hinzufügen. Das wird implizit gehandhabt.
Kendrick Ledet
1
@KendrickLedet, auch wenn Sie keinen UITableViewController verwenden?
Van Du Tran
3
Wie kann ich diese Lösung oben in der Tabellenansicht und unten verwenden?
AustinT
3
Swift 4 Update: refreshControl.addTarget (self, Aktion: "refresh:", für: .valueChanged)
akseli
148

Eine Lösung mit Storyboard und schnellen ...

1.) Öffnen Sie Ihre .storyboard-Datei, wählen Sie einen TableViewController in Ihrem Storyboard aus und aktivieren Sie die Funktion "Table View Controller - Aktualisierung" in den Dienstprogrammen.

Geben Sie hier die Bildbeschreibung ein

2.) Öffnen Sie die zugehörige UITableViewController-Klasse und fügen Sie der viewDidLoad-Methode die folgende Zeile hinzu.

self.refreshControl?.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged)

Bearbeitet für Swift 5.0:

self.refreshControl?.addTarget(self, action: #selector(refresh), for: UIControl.Event.valueChanged)

ODER in Swift 2.2:

self.refreshControl?.addTarget(self, action: #selector(TestTableViewController.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged)

3.) Fügen Sie die folgende Methode über der viewDidLoad-Methode hinzu

func refresh(sender:AnyObject)
{
    // Updating your data here...

    self.tableView.reloadData()
    self.refreshControl?.endRefreshing()
}
Leer
quelle
7
Sie können auch eine Aktualisierungsaktion mit dem Storyboard hinzufügen, indem Sie das Steuerelement von der Aktualisierungssteuerung im Storyboard auf Ihren ViewController ziehen
uiureo
Wenn meine Ladedaten asynchron sind, sollte ich put self.tableView.reloadData()und self.refreshControl?.endRefreshing()im Rückruf?
Qian Chen
Genau! Und stellen Sie die reloadData()in die Hauptwarteschlange, um Ihre Benutzeroberfläche sofort zu aktualisieren: dispatch_async(dispatch_get_main_queue(),{ self.tableView.reloadData() });
Leer
1
Dieser Weg wurde der akzeptierten Antwort vorgezogen, da es dann keine Layoutfehler gibt (zumindest für mich mit Swift 2+)
Ryan Walton
1
Diese Antwort sollte die meisten Stimmen haben und die richtige Antwort sein
krummens
75

Ich möchte eine PRETTY COOL- Funktion erwähnen , die seit iOS 10 enthalten ist:

Vorerst UIRefreshControl wird direkt in jedem der unterstützten UICollectionView, UITableViewund UIScrollView!

Jede dieser Ansichten verfügt über die Instanz-Eigenschaft refreshControl. Dies bedeutet, dass Sie sie nicht mehr als Unteransicht in Ihrer Bildlaufansicht hinzufügen müssen. Sie müssen lediglich Folgendes tun:

@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()
}

Persönlich finde ich es natürlicher, es als Eigenschaft für die Bildlaufansicht zu behandeln, als es als Unteransicht hinzuzufügen, insbesondere weil die einzig geeignete Ansicht als Übersicht für ein UIRefreshControl eine Bildlaufansicht ist, dh die Funktionalität der Verwendung von UIRefreshControl ist nur nützlich beim Arbeiten mit einer Bildlaufansicht; Aus diesem Grund sollte dieser Ansatz für die Einrichtung der Ansicht "Aktualisierungssteuerung" offensichtlicher sein.

Sie haben jedoch weiterhin die Möglichkeit, die addSubviewauf der iOS-Version basierende Version zu verwenden:

if #available(iOS 10.0, *) {
  collectionView.refreshControl = refreshControl
} else {
  collectionView.addSubview(refreshControl)
}
Ahmad F.
quelle
Hey Mann, wie nenne ich das doSomething func? Wenn ich reload.Data aufrufe, möchte es nicht erneut geladen werden!
@ JavierV. Fügen Sie einen Haltepunkt in der doSomethingFunktion hinzu. Wenn dieser erreichbar ist, müssen Sie Ihren Code überprüfen.
Ahmad F
50

Swift 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
}

Und Sie könnten aufhören, sich zu erfrischen mit:

refreshControl.endRefreshing()
Gilad Brunfman
quelle
Vergessen Sie nicht, tableView.reloadData()in Ihrem Beispiel zu erwähnen !
Konstantinos Natsios
Hallo, ich erstelle meine Refresh-Steuerung auf diese Weise : 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 }. Rufen Sie dann endRefreshing () auf, es funktioniert nicht (die Aktualisierungssteuerung wird dort immer noch angezeigt), aber folgen Sie Ihrem Weg, es hat funktioniert. Bitte lassen Sie mich wissen, warum.
Lee
@lee Weil rfControl lokal ist und keinen Zugriff von außen hat. Versuchen Sie, rfControl als globale Variable für die VC zu initialisieren: var rfControl = UIRefreshControl (), und beenden Sie mit rfControl.endRefreshing ()
Gilad Brunfman
Eine Frage: Wo wird das .valueChangedEreignis ausgelöst? Ich verstehe diesen Zusammenhang nicht.
Juniorgarcia
Wenn das UIRefreshControl ausgelöst wird, wie Sie sehen, wenn SieTarget hinzufügen: refreshControl.addTarget (self, action: #selector (self.refresh), für: UIControlEvents.valueChanged)
Gilad Brunfman
9

In Swift verwenden Sie dies,

Wenn Sie Pull zum Aktualisieren in WebView haben möchten,

Probieren Sie diesen Code aus:

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()
}
Mohammad Zaid Pathan
quelle
Danke mein Herr! Das Problem eines Noobs, das ich beim Lernen hatte, wurde gelöst.
Adrian David Smith
5

Anhils Antwort hat mir sehr geholfen.

Nachdem ich weiter experimentiert hatte, bemerkte ich jedoch, dass die vorgeschlagene Lösung manchmal einen nicht so hübschen UI-Fehler verursacht .

Stattdessen hat sich dieser Ansatz * für mich bewährt.

* Swift 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
Leverin
quelle
2

Der Fehler sagt Ihnen, dass er refreshnicht initialisiert ist. Beachten Sie, dass Sie gewählt haben , um refreshnicht optional, das in Swift bedeutet , dass es hat einen Wert haben , bevor Sie anrufen super.init(oder implizit genannt, die Ihr Fall zu sein scheint). Machen refreshSie entweder optional (wahrscheinlich was Sie wollen) oder initialisieren Sie es auf irgendeine Weise.

Ich würde vorschlagen, die Swift-Einführungsdokumentation noch einmal zu lesen, die dies ausführlich behandelt.

Eine letzte Sache, die nicht Teil der Antwort ist, wie von @Anil hervorgehoben, gibt es eine eingebaute Pull-to-Refresh-Steuerung in iOS UIRefresControl, die einen Blick wert sein könnte.

JustSid
quelle
2

Ich habe eine RSS-Feed-App erstellt, in der ich eine Pull-To-Aktualisierungsfunktion habe , die ursprünglich einige der oben aufgeführten Probleme hatte.

Um die Antworten der Benutzer oben zu ergänzen, habe ich überall nach meinem Anwendungsfall gesucht und konnte ihn nicht finden. Ich habe Daten aus dem Internet heruntergeladen (RSSFeed) und wollte meine Tabellenansicht der Geschichten zum Aktualisieren aufrufen.

Was oben erwähnt wurde, deckt die richtigen Bereiche ab, aber mit einigen der Probleme, die Menschen haben, habe ich Folgendes getan und es ist ein Vergnügen:

Ich habe den Ansatz von @Blankarsch gewählt und bin zu meinem main.storyboard gegangen und habe die Tabellenansicht ausgewählt, um die Aktualisierung zu verwenden. Dann wurde nicht erwähnt, dass IBOutlet und IBAction erstellt werden, um die Aktualisierung effizient zu nutzen

//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()
}

Hoffe das hilft jemandem in der gleichen Situation wie ich

Dom Bryan
quelle
2
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()
}
Hiren
quelle
2

Einzelheiten

  • Xcode Version 10.3 (10G8), Swift 5

Eigenschaften

  • Möglichkeit, programmgesteuert "Pull to Refresh" zu erstellen
  • Schutz vor Multi-Pull-to-Refresh-Ereignissen
  • Möglichkeit zur weiteren Animation der Aktivitätsanzeige beim Umschalten des View Controllers (z. B. bei TabController)

Lösung

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) }
}

Verwendung

// 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()

Vollständige Probe

Vergessen Sie nicht, den Lösungscode hier hinzuzufügen

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()
    }
}
Wassili Bodnarchuk
quelle
2

Swift 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
    }
Gurjinder Singh
quelle
1

Ich schlage vor, eine Erweiterung von Pull To Refresh zu erstellen, die in jeder Klasse verwendet werden kann.

1) Erstellen Sie eine leere Swift-Datei: Datei - Neu - Datei - Swift-Datei.

2) Fügen Sie Folgendes hinzu

    //  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) Rufen Sie in Ihrem View Controller die folgenden Methoden auf:

  override func viewWillAppear(animated: Bool) {

self.makePullToRefreshToTableView(bidderListTable, triggerToMethodName: "pullToRefreshBidderTable")
}

4) Irgendwann wollten Sie die Aktualisierung beenden:

  func pullToRefreshBidderTable() {
self.makePullToRefreshEndRefreshing("bidderListTable")    
//Code What to do here.
}
OR    
self.makePullToRefreshEndRefreshing("bidderListTable")
AG
quelle
1
Ihr Code ist mit Projektname und Copyright-Hinweis, möglicherweise nicht gut für Sie :). Welchen Code Sie auch hier gepostet haben, sollte für alle kostenlos sein
Anil Varghese
Danke Anil! Ich habe vergessen, diese zu entfernen.
AG
1

Damit der Pull aktualisiert wird, verwende ich

DGElasticPullToRefresh

https://github.com/gontovnik/DGElasticPullToRefresh

Installation

pod 'DGElasticPullToRefresh'

import DGElasticPullToRefresh

und fügen Sie diese Funktion in Ihre schnelle Datei ein und rufen Sie diese Funktion von Ihrem aus auf

überschreiben func viewWillAppear (_ animiert: 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!)
 }

Und vergessen Sie nicht, den Verweis zu entfernen, während die Ansicht verschwindet

Um Pull zum Aktualisieren zu entfernen, geben Sie diesen Code in Ihre ein

überschreiben func viewDidDisappear (_ animiert: Bool)

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

 }

Und es wird so aussehen

Geben Sie hier die Bildbeschreibung ein

Viel Spaß beim Codieren :)

Azharhussain Shaikh
quelle
1

Sie können dies erreichen, indem Sie nur wenige Codezeilen verwenden. Warum stecken Sie also in einer Bibliothek oder Benutzeroberfläche von Drittanbietern fest? Pull to Refresh ist in iOS integriert. Sie könnten dies schnell tun

Geben Sie hier die Bildbeschreibung ein

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  
}
Mr.Javed Multani
quelle
0

Sie können diese Unterklasse von tableView verwenden:

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 - Ändern Sie im Interface Builder die Klasse Ihrer tableView in PullToRefreshTableViewoder erstellen Sie eine PullToRefreshTableViewprogrammgesteuerte

2 - Implementieren Sie den PullToRefreshTableViewDelegateController in Ihrer Ansicht

3 - tableViewDidStartRefreshing(tableView: PullToRefreshTableView)wird in Ihrem View Controller aufgerufen, wenn die Tabellenansicht aktualisiert wird

4 - Rufen Sie yourTableView.endRefreshing()an, um die Aktualisierung zu beenden

Chuy47
quelle
0

So habe ich es mit Xcode 7.2 zum Laufen gebracht, was meiner Meinung nach ein großer Fehler ist. Ich benutze es in meinem UITableViewControllerInnerenviewWillAppear

refreshControl = UIRefreshControl()
refreshControl!.addTarget(self, action: "configureMessages", forControlEvents: .ValueChanged)
refreshControl!.beginRefreshing()

configureMessages()

func configureMessages() {
    // configuring messages logic here

    self.refreshControl!.endRefreshing()
}

Wie Sie sehen können, muss ich die configureMessage()Methode buchstäblich aufrufen , nachdem ich meine eingerichtet habe. UIRefreshControlDanach funktionieren nachfolgende Aktualisierungen einwandfrei.

jaytrixz
quelle
-1

Andere Antworten sind richtig, aber für weitere Details überprüfen Sie diesen Beitrag Pull to Refresh

Aktivieren Sie die Aktualisierung im Storyboard

Wenn Sie mit einem UITableViewController arbeiten, ist die Lösung recht einfach: Wählen Sie zunächst den Tabellenansichts-Controller in Ihrem Storyboard aus, öffnen Sie den Attributinspektor und aktivieren Sie die Aktualisierung:

Ein UITableViewController ist standardmäßig mit einem Verweis auf ein UIRefreshControl ausgestattet. Sie müssen lediglich einige Dinge verkabeln, um die Aktualisierung zu initiieren und abzuschließen, wenn der Benutzer herunterfährt.

ViewDidLoad () überschreiben

Fügen Sie in Ihrer Überschreibung von viewDidLoad () ein Ziel hinzu, um die Aktualisierung wie folgt durchzuführen:

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. Da ich als Aktionsargument "handleRefresh:" (beachten Sie den Doppelpunkt!) Angegeben habe, muss ich eine Funktion in dieser UITableViewController-Klasse mit demselben Namen definieren. Zusätzlich sollte die Funktion ein Argument annehmen
  2. Wir möchten, dass diese Aktion für das UIControlEvent mit dem Namen ValueChanged aufgerufen wird
  3. Vergiss nicht anzurufen refreshControl.endRefreshing()

Für weitere Informationen gehen Sie bitte auf Link und alle Gutschriften gehen an diesen Beitrag

Singhak
quelle
Während dies theoretisch die Frage beantworten kann, wäre es vorzuziehen , die wesentlichen Teile der Antwort hier aufzunehmen und den Link als Referenz bereitzustellen.
Tunaki