J'ai configuré un UIRefreshControl dans mon UITableViewController (qui est à l'intérieur d'un UINavigationController) et cela fonctionne comme prévu (c'est-à-dire que le pull down déclenche l'événement correct). Cependant, si j'appelle par programme la beginRefreshing
méthode d'instance sur le contrôle d'actualisation comme:
[self.refreshControl beginRefreshing];
Rien ne se passe. Il doit s'animer et afficher le spinner. La endRefreshing
méthode fonctionne correctement lorsque j'appelle cela après l'actualisation.
J'ai créé un projet de prototype de base avec ce comportement et cela fonctionne correctement lorsque mon UITableViewController est ajouté directement au contrôleur de vue racine du délégué d'application, par exemple:
self.viewController = tableViewController;
self.window.rootViewController = self.viewController;
Mais si j'ajoute d'abord le tableViewController
à un UINavigationController, puis ajoute le contrôleur de navigation en tant que rootViewController
, la beginRefreshing
méthode ne fonctionne plus. Par exemple
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
self.viewController = navController;
self.window.rootViewController = self.viewController;
Mon sentiment est que cela a quelque chose à voir avec les hiérarchies de vues imbriquées dans le contrôleur de navigation qui ne jouent pas bien avec le contrôle de rafraîchissement - des suggestions?
Merci
UITableViewController a la propriété automaticAdjustsScrollViewInsets après iOS 7. La vue de table peut déjà avoir contentOffset, généralement (0, -64).
Ainsi, la bonne façon d'afficher refreshControl après le début de l'actualisation par programmation consiste à ajouter la hauteur de refreshControl à contentOffset existant.
la source
-64
vaut mieux utiliser-self.topLayoutGuide.length
Voici une extension Swift utilisant les stratégies décrites ci-dessus.
la source
sendActionsForControlEvents(UIControlEvents.ValueChanged)
à la fin de cette fonction, sinon la logique logique d'actualisation réelle ne sera pas exécutée.Aucune des autres réponses n'a fonctionné pour moi. Ils feraient apparaître et tourner le spinner, mais l'action de rafraîchissement elle-même ne se produirait jamais. Cela marche:
Notez que cet exemple utilise une vue de table, mais il aurait tout aussi bien pu être une vue de collection.
la source
SVPullToRefresh
, comment le retirer par programme?[tableView triggerPullToRefresh];
" Voir: github.com/samvermette/ SVPullToRefreshscrollView.contentOffset = CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height)
L'approche déjà mentionnée:
rendrait le spinner visible. Mais cela n'animerait pas. La seule chose que j'ai changé est l'ordre de ces deux méthodes et tout a fonctionné:
la source
Pour Swift 4 / 4.1
Un mélange de réponses existantes fait le travail pour moi:
J'espère que cela t'aides!
la source
Voici l' extension Swift 3 et ultérieure qui montre le spinner et l'anime.
la source
asyncAfter
fait ce qui fait fonctionner l'animation spinner (iOS 12.3 / Xcode 10.2)Voir aussi cette question
UIRefreshControl n'affiche pas de spiny lors de l'appel de beginRefreshing et contentOffset est 0
Cela ressemble à un bogue pour moi, car cela ne se produit que lorsque la propriété contentOffset de la tableView est à 0
J'ai corrigé cela avec le code suivant (méthode pour UITableViewController):
la source
beginRefreshing
, seulement que son état change. Comme je le vois, il s'agit d'empêcher de lancer l'action d'actualisation deux fois, de sorte qu'une actualisation appelée par programme serait toujours en cours d'exécution, une action initiée par l'utilisateur n'en démarrera pas une autre.Cela fonctionne parfaitement pour moi:
Swift 3:
la source
Pour Swift 5, pour moi, la seule chose qui manquait était d'appeler
refreshControl.sendActions(.valueChanged)
. J'ai fait une extension pour le rendre plus propre.la source
En plus de la solution @Dymitry Shevchenko.
J'ai trouvé une bonne solution de contournement à ce problème. Vous pouvez créer une extension pour
UIRefreshControl
cette méthode de remplacement:Vous pouvez utiliser une nouvelle classe en définissant une classe personnalisée dans l' Inspecteur d'identité pour le contrôle d'actualisation dans Interface Builder.
la source
Fort Swift 2.2+
la source
Si vous utilisez Rxswift pour swift 3.1, vous pouvez utiliser ci-dessous:
Cela fonctionne pour swift 3.1, iOS 10.
la source
sendActions
déclencheurrx
qui rend cette réponse liée auRxSwift
cas où tout le monde se demande à première vueself.tableView.setContentOffset(CGPoint(x:0, y:self.tableView.contentOffset.y - (refreshControl.frame.size.height)), animated: true)
testé sur Swift 5
utiliser ceci dans
viewDidLoad()
la source
J'utilise la même technique pour afficher le signe visuel «les données sont mises à jour». Un utilisateur de résultat apportera une application à partir de l'arrière-plan et les flux / listes seront mis à jour avec l'interface utilisateur, comme les utilisateurs tirent des tables pour se rafraîchir. Ma version contient 3 choses
1) Qui envoie "réveiller"
2) Observateur dans UIViewController
3) Le protocole
la source