ios - custom - maps swift 3
¿Cómo usar pull para actualizar en Swift? (13)
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.
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.
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.
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()
}
Espero que esto ayude a cualquiera en la misma situación que yo
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.
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)
}
- 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
- Nos gustaría que se llamara a esta acción para UIControlEvent llamada ValueChanged
- 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
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("")
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
Feliz codificación :)
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")
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.
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()
}
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
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: "refresh:", forControlEvents: UIControlEvents.ValueChanged)
tableView.addSubview(refreshControl) // not required when using UITableViewController
}
func refresh(sender:AnyObject) {
// Code to refresh table view
}
En algún punto podrías terminar refrescante.
refreshControl.endRefreshing()
Swift 3
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)
}
func refresh(_ sender: Any) {
// your code to refresh tableView
}
Y puedes dejar de refrescarte con:
refreshControl.endRefreshing()