tab bar ios iphone objective-c refresh uirefreshcontrol

ios - uitabbarcontroller swift 4



Control UIRefresh atascado después de cambiar las pestañas en UITabBarController (14)

Acabo de ver lo mismo. Lo que terminé haciendo es endRefreshing on viewWillDisappear y eso al menos elimina este problema. Sin embargo, volviendo a la pestaña, espero que comience a girar nuevamente cuando reinicio el proceso de actualización y vuelvo a llamar a BeginRefreshing, pero no es así. Lo hace en el caso cuando profundizo la navegación y luego regreso.

Tengo un UITableViewController como controlador de vista raíz en un UINavigationController, que a su vez es uno de los controladores de vista en un UITabBarController. Todo conectado en Storyboard.

También configuré el UIRefreshControl para mi tabla en el Storyboard, y normalmente parece que debería hacerlo al tirar:

Sin embargo, si cambio entre mis otras pestañas una o dos veces, se verá así:

No está girando ni nada, solo se atasca "lleno", y permanece así hasta que lo jale por completo y active una actualización.

Cualquier idea o sugerencia apreciará.


Después de encontrarme con el mismo problema varias veces, decidí crear una biblioteca para ello SwiftPullToRefresh .

Como se dijo antes, refreshControl debe refreshControl en viewDidDisappear(_:) y comenzar en viewWillAppear(_:) .

Al iniciar la animación refreshControl programación, tableView.contentOffset debe configurarse en el valor apropiado.

tableView.setContentOffset(CGPoint(x: 0, y: -(refreshControl?.bounds.height ?? 60) - topOffset), animated: true) var topOffset: CGFloat { if let navigationBar = navigationController?.navigationBar, navigationBar.isTranslucent == true { return navigationBar.bounds.height + UIApplication.shared.statusBarFrame.height } else { return 0 } }


Espero poder ayudar a resolver este problema finalmente:

Hay un problema al utilizar UITableView con un control Pull-To-Refresh. Esto se puede resolver FÁCILMENTE, agregando un UITableViewController.

UITableViewController *tableController = [[UITableViewController alloc] init]; tableController.automaticallyAdjustsScrollViewInsets = NO; [tableController willMoveToParentViewController:self]; [self addChildViewController:tableController]; tableController.tableView = self.containerTableView; tableController.refreshControl = self.refreshControl;

De esta manera, simplemente envuelve su UITableView dentro de un controlador para el cual [self.refreshControl endRefreshing] funcionará completamente bien dentro de viewWillAppear o viewWillDisappear . En algunos casos es posible que tenga que llamarlo en ambos.

¡Espero que esto ayude! :)


La mejor solución en Swift:

override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) //fixes bug with refreshControl freezing while switching tabs if tableView.contentOffset.y < 0 { tableView.contentOffset = .zero } }


La siguiente solución puede ayudarte.

CGFloat yTableViewOffset; - (void)viewDidLoad { yTableViewOffset = kNilOptions; } - (void)viewWillAppear:(BOOL)animated { if(yTableViewOffset != kNilOptions) { CGPoint offset = CGPointMake(tableView.contentOffset.x, yTableViewOffset); [refreshControl beginRefreshing]; tableView.contentOffset = offset; } } - (void)viewWillDisappear:(BOOL)animated { if(refreshControl.isRefreshing) { yTableViewOffset = tableView.contentOffset.y; [refreshControl endRefreshing]; } }


Las respuestas en esta question resolvieron mi problema.

Básicamente, deteniendo e iniciando el giro nuevamente en viewWillAppear


Mientras el control de actualización está girando, si presenta algún otro controlador y vuelve antes de "finalizar la actualización"; la animación de actualización se atascará.

Ninguna de las respuestas anteriores funcionó para mí, y no quería configurar Bool y seguirlo durante todo el ciclo de vida de un controlador de vista.

Mi solución es agregar el siguiente código al final de viewWillAppear.

en Objc;

if (self.refreshControl.isRefreshing) { [self.refreshControl endRefreshing]; [self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControl.frame.size.height) animated: true]; [self.refreshControl beginRefreshing]; }

en Swift;

if self.refreshControl.isRefreshing { self.refreshControl.endRefreshing self.tableView.setContentOffset(CGPoint(x: 0, y: self.tableView.contentOffset.y-self.refreshControl.frame.size.height), animated: true) self.refreshControl.beginRefreshing; }

La lógica es; siempre que atrape el control de actualización está en estado de animación, lo detendrá sin saber si está atascado o no y volverá a ejecutar la animación.

Espero eso ayude.


No pude hacer que la llamada a endRefreshing funcionara antes de que ocurriera la navegación, así que abordé el problema desde el otro extremo y en la vista. Apareceré. Verifico si el valor de TableView contentOffset es un número negativo devuelve el valor de tableView a 0.

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; if (self.tableView.contentOffset.y < 0) { [self.tableView setContentOffset:CGPointZero animated:YES]; } }


Para resumir y proporcionar una solución completa.

El problema:

Si UIRefreshControl está animando durante la transición de pantalla, permanecerá visible pero no estará animando. Video https://vid.me/Bkb7

Además, si se inició la animación de extracción para actualizar, pero no se completó, y luego se realizó la transición, UIRefreshControl se ocultará pero se atascará. Video https://vid.me/Bkb7

Solución:

Inicie la animación UIRefreshControl en viewWillAppear y finalícela en viewDidDisappear. Guarde el estado del proceso de actualización para saber cuándo mostrar UIRefreshControl.

Bellow es la solución completa que también maneja la animación adecuada y el tirón simple para actualizar la animación.

Añadir a UITableView o subclase

Inicialización:

/// Refresh indicator var refreshControl = UIRefreshControl() /// Refresh state var isRefreshing = false /// Refresh controll update funcion. Set to enable pull to refresh var refreshControllUpdateFunction: (() -> ())? /// Prepeares UIRefreshControll. Call from init func initRefreshControl(){ addSubview(refreshControl) refreshControl.addTarget(self, action: "refreshControllTarget", forControlEvents: .ValueChanged) refreshControl.beginRefreshing() isRefreshing = true }

Controladores de eventos de supervisión:

/// Call on viewWillApper func superviewWillApper(){ if isRefreshing && !refreshControl.refreshing{ startRefreshAnimation() } } /// Call on viewDidDisapper func superviewDidDisappear(){ endRefreshAnimation(false, dataFetched: !isRefreshing) }

Controlador de animación UIRefreshControl:

/// Presents animating UIRefreshControll func startRefreshAnimation(){ refreshControl.beginRefreshing() contentOffset = CGPointMake(0, -refreshControl.bounds.size.height) isRefreshing = true } /// Hides UIRefreshControll and saves state of refresh func endRefreshAnimation(wasEmpty: Bool, dataFetched: Bool){ refreshControl.endRefreshing() isRefreshing = !dataFetched if !wasEmpty{ setContentOffset(CGPointZero, animated: true) }else{ setContentOffset(CGPointZero, animated: false) } }

Añadir

table.isRefreshing = true

al comienzo de la llamada de actualización.

Resultado del video https://vid.me/LyuI


Quiero algunos puntos y me gusta la solución de Albert pero no su estilo.

- (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; _table.contentOffset = CGPointMake(_table.contentOffset.x, _table.contentOffset.y + 1.0f); } - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; _table.contentOffset = CGPointMake(_table.contentOffset.x, _table.contentOffset.y - 1.0f); }


Sé que esto es increíblemente tarde, pero me parece mejor tarde que nunca.

Desafortunadamente, ninguna de las respuestas dadas funcionó para mí. Lo único que funcionó fue este terrible código en viewWillAppear:

self.refreshControl = nil; UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(refreshFunction) forControlEvents:UIControlEventValueChanged]; self.refreshControl = refreshControl;

Básicamente, recreo el UIRefreshControl cada vez que aparece la vista. Funciona, aunque da la siguiente advertencia:

Intentar cambiar el control de actualización mientras no está inactivo no se recomienda y probablemente no funcione correctamente.

Sinceramente, me sorprende que esto siga siendo un problema (aún lo veo en iOS 9 ahora). Esperemos que esto pueda ser útil para otras personas.


Simplemente llamando a endRefreshing en viewWillDisappear: solucioné todos los problemas para mí.

- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.refreshControl endRefreshing]; }

Al hacer lo mismo en viewWillAppear: el control de actualización viewWillAppear: extraña al tirar de la mesa.


Tengo un collectionView y configuré su contentInset.

Al presionar algunos ViewControllers, luego presione el botón de inicio, y retroceda y vuelva a aparecer, el control UIRefresh siempre está en la parte superior.

Finalmente utilizo este código temporalmente, evítalo. (Feo pero para siempre siempre se muestra arriba)

- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [self.refreshControl endRefreshing]; CGPoint currentContentOffset = self.collectionView.contentOffset; [self.collectionView setContentOffset:CGPointMake(currentContentOffset.x, currentContentOffset.y - 1.0f) animated:YES]; } - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; CGPoint currentContentOffset = self.collectionView.contentOffset; [self.collectionView setContentOffset:CGPointMake(currentContentOffset.x, currentContentOffset.y + 1.0f) animated:YES]; }


user2009606 estaba casi correcto, lo arreglé llamando

[refreshControl endRefreshing];

En

viewWillAppear:

El refreshControl ahora se comporta correctamente después de cambiar las pestañas, independientemente de su estado.