¿Cómo usar pull para actualizar en Swift?

Estoy construyendo un lector de RSS que usa velozmente y necesito implementar la funcionalidad de extracción para volver a cargar.

Así es como estoy tratando de hacerlo.

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

Estoy obteniendo :

Propiedad ‘self.refresh’ no inicializada en la llamada super.init

Por favor, ayúdame a entender el comportamiento de los reconocedores Gesture. Un código de muestra que funcione será de gran ayuda.

Gracias.

Pull to refresh está construido en iOS. Podrías hacer esto en rápido como

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

En algún punto podrías terminar refrescante.

 refreshControl.endRefreshing() 

Una solución con guión gráfico y veloz …

1.) Abra su archivo .storyboard, seleccione TableViewController en su guión gráfico y “Habilite” el controlador Table View – Función de actualización en las Utilidades.

enter image description here

2.) Abra el UITableViewController-Class asociado y agregue la siguiente línea en el viewDidLoad-Method.

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

O en Swift 2.2:

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

3.) Agregue el siguiente Método arriba del método viewDidLoad

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

iOS 10 – Swift 3 (también aplicable para iOS 11 – Swift 4)

Me gustaría mencionar una característica PRETTY COOL que se ha incluido desde iOS 10, que es:

Por ahora, UIRefreshControl se admite directamente en cada uno de UICollectionView , UITableView y UIScrollView .

Cada una de estas vistas tiene la propiedad de instancia refreshControl , lo que significa que ya no es necesario agregarla como una subvista en la vista de desplazamiento , todo lo que tiene que hacer es:

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

Personalmente, me parece más natural tratarlo como una propiedad de la vista de desplazamiento que agregarlo como subvista, especialmente porque la única vista adecuada para ser una supervista para una UIRefreshControl es una vista de desplazamiento, es decir, la funcionalidad de usar UIRefreshControl es solo útil cuando se trabaja con una vista de desplazamiento; Es por eso que este enfoque debería ser más obvio para configurar la vista de control de actualización.

Sin embargo, todavía tienes la opción de usar addSubview función de la versión de iOS:

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

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 refresh tableView } 

Y puedes dejar de refrescarte con:

 refreshControl.endRefreshing() 

En Swift usa esto,

Si desea tener pull para actualizar en WebView,

Entonces prueba este código:

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

La respuesta de Anhil me ayudó mucho.

Sin embargo, después de experimentar más noté que la solución sugerida a veces causa un problema de IU no tan bonito.

En cambio, ir por este enfoque * me sirvió de algo.

* 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 

Lo que el error te está diciendo es que la refresh no se ha inicializado. Tenga en cuenta que eligió hacer que refresh no sea opcional, lo que en Swift significa que debe tener un valor antes de llamar a super.init (o se llama implícitamente, lo que parece ser su caso). Haga la refresh opcional (probablemente lo que desee) o inicialícela de alguna manera.

Sugiero leer la documentación introductoria de Swift otra vez, que cubre esto en gran medida.

Una última cosa, que no forma parte de la respuesta, como lo señala @Anil, existe un pull integrado para actualizar el control en iOS llamado UIRefresControl , que podría ser algo que valga la pena investigar.

Creé una aplicación de alimentación RSS en la que tengo una función de extracción para actualizar que originalmente tenía algunos de los problemas enumerados anteriormente.

Pero para agregar a las respuestas de los usuarios anteriores, estaba buscando mi caso de uso en todas partes y no pude encontrarlo. Estaba descargando datos de la web (RSSFeed) y quería desplegar mi tabla Vista de historias para actualizar.

Lo que mencioné anteriormente cubre las áreas correctas pero con algunos de los problemas que la gente está teniendo, esto es lo que hice y funciona de maravilla:

Tomé el enfoque de @Blankarsch y fui a mi main.storyboard y seleccioné la vista de tabla para usar refresh, luego lo que no se mencionó es crear IBOutlet e IBAction para usar el refresh de manera eficiente

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

Sugiero que haga una extensión de extracción para actualizar en todas las clases.

1) Haga un archivo rápido vacío: Archivo – Nuevo – Archivo – Swift File.

2) Agregue los siguientes

  // 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) En su controlador de vista llame a estos métodos como:

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

4) En algún momento quisiste terminar refrescante:

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

puedes usar esta subclase 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.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 – en el constructor de interfaces cambie la clase de su tableView a PullToRefreshTableView o cree un PullToRefreshTableView programáticamente

2: implementa el PullToRefreshTableViewDelegate en tu controlador de vista

3 – tableViewDidStartRefreshing(tableView: PullToRefreshTableView) se llamará en su controlador de vista cuando la vista de tabla comience a refrescarse

4 – llame a yourTableView.endRefreshing() para finalizar la actualización

Así es como lo hice funcionar usando Xcode 7.2, que creo que es un error importante. Lo estoy usando dentro de mi UITableViewController dentro de mi viewWillAppear

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

Como puede ver, literalmente tengo que llamar al método configureMessage() después de configurar mi UIRefreshControl , luego de eso, las subsiguientes actualizaciones funcionarán bien.

Para la extracción de refrescar estoy usando

DGElasticPullToRefresh

https://github.com/gontovnik/DGElasticPullToRefresh

Instalación

pod ‘DGElasticPullToRefresh’

 import DGElasticPullToRefresh 

y coloque esta función en su archivo rápido y llame a esta función desde su

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

Y no te olvides de eliminar la referencia mientras que la vista se desvanecerá

para eliminar la atracción para actualizar ponga este código en su

anular func viewDidDisappear (_ animated: Bool)

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

Y se verá como

enter image description here

Feliz encoding 🙂

Otras respuestas son correctas, pero para obtener más detalles, consulte este mensaje Tire para actualizar

Habilite la actualización en Storyboard

Cuando trabajas con un UITableViewController, la solución es bastante simple: primero, selecciona el controlador de vista de tabla en tu guión gráfico, abre el inspector de atributos y habilita la actualización:

Un UITableViewController viene equipado con una referencia a un UIRefreshControl listo para usar. Simplemente necesita cablear algunas cosas para iniciar y completar la actualización cuando el usuario tira hacia abajo.

Reemplazar viewDidLoad ()

En su reemplazo de viewDidLoad (), agregue un destino para manejar la actualización de la siguiente manera:

 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. Como he especificado “handleRefresh:” (¡fíjese en los dos puntos!) Como argumento de acción, necesito definir una función en esta clase UITableViewController con el mismo nombre. Además, la función debería tomar un argumento
  2. Nos gustaría que se llamara a esta acción para UIControlEvent llamada ValueChanged
  3. No olvide llamar a refreshControl.endRefreshing()

Para obtener más información, vaya a mencionar Enlace y todo el crédito va a esa publicación