Comment utiliser tirer pour actualiser dans Swift?

Je construis un lecteur RSS en utilisant swift et j'ai besoin d'implémenter la fonctionnalité de rechargement.

Voici comment j'essaie de le faire.

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

Je reçois :

La propriété 'self.refresh' n'est pas initialisée lors de l'appel super.init

S'il vous plaît aidez-moi à comprendre le comportement des reconnaisseurs de gestes. Un exemple de code sera très utile.

Merci.

Pull to refresh est construit dans iOS. Vous pourriez le faire rapidement comme

 var refreshControl: UIRefreshControl! override func viewDidLoad() { super.viewDidLoad() refreshControl = UIRefreshControl() refreshControl.atsortingbutedTitle = NSAtsortingbutedSsortingng(ssortingng: "Pull to refresh") refreshControl.addTarget(self, action: "refresh:", forControlEvents: UIControlEvents.ValueChanged) tableView.addSubview(refreshControl) // not required when using UITableViewController } func refresh(sender:AnyObject) { // Code to refresh table view } 

À un certain moment, vous pourriez terminer rafraîchissant.

 refreshControl.endRefreshing() 

Une solution avec storyboard et rapide …

1.) Ouvrez votre file .storyboard, select un TableViewController dans votre storyboard et "Activer" la fonctionnalité Table View Controller – Refreshing dans les utilitaires.

entrez la description de l'image ici

2.) Ouvrez la class UITableViewController associée et ajoutez la ligne suivante dans la méthode viewDidLoad.

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

OU dans Swift 2.2:

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

3.) Ajoutez la méthode suivante au-dessus de la méthode viewDidLoad

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

iOS 10 – Swift 3 (également applicable pour iOS 11 – Swift 4)

Je voudrais mentionner une fonctionnalité PRETTY COOL qui a été incluse depuis iOS 10, qui est:

Pour l'instant, UIRefreshControl est directement supporté dans UICollectionView , UITableView et UIScrollView !

Chacune de ces vues possède la propriété d'occurrence refreshControl , ce qui signifie qu'il n'est plus nécessaire de l'append en tant que sous-vue dans votre vue de défilement , tout ce que vous avez à faire est:

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

Personnellement, je trouve plus naturel de la traiter comme une propriété de scroll plutôt que de l'append sous forme de sous-vue, d'autant plus que la seule vue appropriée en tant que vue d'set pour UIRefreshControl est une scrollview, autrement dit la fonctionnalité d'utilisation de UIRefreshControl utile lorsque vous travaillez avec une vue déroulante; C'est pourquoi cette approche devrait être plus évidente pour configurer la vue de contrôle d'actualisation.

Swift 3

 var refreshControl: UIRefreshControl! override func viewDidLoad() { super.viewDidLoad() refreshControl = UIRefreshControl() refreshControl.atsortingbutedTitle = NSAtsortingbutedSsortingng(ssortingng: "Pull to refresh") refreshControl.addTarget(self, action: #selector(refresh), for: .valueChanged) tableView.addSubview(refreshControl) } func refresh(_ sender: Any) { // your code to refresh tableView } 

Et vous pourriez arrêter de rafraîchir avec:

 refreshControl.endRefreshing() 

Dans Swift, utilisez ceci,

Si vous voulez tirer pour actualiser dans WebView,

Alors essayez ce code:

 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.atsortingbutedTitle = NSAtsortingbutedSsortingng(ssortingng: "Pull down to refresh...") YourWebView.scrollView.addSubview(refreshController) } func refreshWebView(refresh:UIRefreshControl){ YourWebView.reload() refresh.endRefreshing() } 

La réponse d'Anhil m'a beaucoup aidé.

Cependant, après avoir expérimenté plus loin, j'ai remarqué que la solution suggérée parfois provoque un petit problème d'interface user .

Au lieu de cela, aller pour cette approche * a fait l'affaire pour moi.

* 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 

Ce que l'erreur vous dit, c'est que l' refresh n'est pas initialisée. Notez que vous avez choisi de rendre l' refresh non optionnelle, ce qui dans Swift signifie qu'elle doit avoir une valeur avant d'appeler super.init (ou elle est implicitement appelée, ce qui semble être votre cas). Soit refresh facultatif (probablement ce que vous voulez) ou initialisez-le d'une certaine manière.

Je suggère de lire à nouveau la documentation d'introduction de Swift, qui couvre ceci de manière très détaillée.

Une dernière chose, pas une partie de la réponse, comme l'a souligné @Anil, il y a un pull embedded pour rafraîchir le contrôle dans iOS appelé UIRefresControl , qui pourrait être quelque chose qui mérite d'être UIRefresControl .

J'ai créé une application de stream RSS dans laquelle j'ai une fonction de rafraîchissement qui présentait initialement certains des problèmes énumérés ci-dessus.

Mais pour append aux réponses des users ci-dessus, je cherchais partout mon cas d'utilisation et ne pouvais pas le find. Je téléchargeais des données du web (RSSFeed) et je voulais tirer sur ma tableAffiche des histoires à rafraîchir.

Ce qui est mentionné ci-dessus couvre les bonnes zones, mais avec certains des problèmes que les gens ont, voici ce que j'ai fait et cela fonctionne un régal:

J'ai pris l'approche de @Blankarsch et suis allé à mon main.storyboard et select la vue de table pour employer l'actualisation, alors ce qui n'a pas été mentionné crée IBOutlet et IBAction pour employer la régénération efficacement

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

Je suggère de faire une extension de traction à rafraîchir à utiliser dans chaque class.

1) Faire un file rapide vide: Fichier – Nouveau – Fichier – Fichier Swift.

2) Ajouter le suivant

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

3) Dans Your View View, appelez ces methods comme suit:

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

4) À un moment donné, vous vouliez terminer de rafraîchir:

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

vous pouvez utiliser cette sous-class de 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.atsortingbutedTitle = NSAtsortingbutedSsortingng(ssortingng: "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 – dans le générateur d'interface, changez la class de votre tableView en PullToRefreshTableView ou créez un PullToRefreshTableView programmation

2 – implémenter le PullToRefreshTableViewDelegate dans votre controller de vue

3 – tableViewDidStartRefreshing(tableView: PullToRefreshTableView) sera appelée dans votre controller de vue lorsque la vue de la table commencera à être rafraîchie

4 – appelez yourTableView.endRefreshing() pour terminer l'actualisation

C'est ainsi que je l'ai fait fonctionner en utilisant Xcode 7.2, ce qui me semble être un bug majeur. Je l'utilise dans mon UITableViewController intérieur de ma viewWillAppear

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

Comme vous pouvez le voir, je dois littéralement appeler la méthode configureMessage() après avoir configuré mon UIRefreshControl après quoi les actualisations suivantes fonctionneront UIRefreshControl .

Pour le pull à rafraîchir j'utilise

DGElasticPullToRefresh

https://github.com/gontovnik/DGElasticPullToRefresh

Installation

pod 'DGElasticPullToRefresh'

 import DGElasticPullToRefresh 

et mettez cette fonction dans votre file rapide et appelez cette fonction de votre

override func viewWillAppear (_ animé: 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!) } 

Et n'oubliez pas de supprimer la reference tandis que la vue disparaîtra

pour retirer tirer pour actualiser mettre ce code dans votre

override func viewDidDisappear (_ animé: Bool)

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

Et ça va ressembler

entrez la description de l'image ici

Codage heureux 🙂

D'autres réponses sont correctes mais pour plus de détails, consultez ce message Tirez pour rafraîchir

Activer l'actualisation dans Storyboard

Lorsque vous travaillez avec un UITableViewController, la solution est assez simple: d'abord, select le controller de vue de table dans votre storyboard, ouvrez l'inspecteur d'attributes et activez l'actualisation:

Un UITableViewController est équipé d'une reference à un UIRefreshControl hors de la boîte. Vous devez simplement câbler quelques éléments pour initier et terminer l'actualisation lorsque l'user descend.

Remplacer viewDidLoad ()

Dans votre rlocation de viewDidLoad (), ajoutez une cible pour gérer l'actualisation comme suit:

 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. Comme j'ai spécifié "handleRefresh:" (notez les deux-points!) Comme argument d'action, j'ai besoin de définir une fonction dans cette class UITableViewController avec le même nom. En outre, la fonction doit prendre un argument
  2. Nous aimerions que cette action soit appelée pour l'UIControlEvent appelé ValueChanged
  3. N'oubliez pas d'appeler refreshControl.endRefreshing()

Pour plus d'informations S'il vous plaît aller à mentionner le lien et tout le crédit va à ce post