Skonfigurowałem UIRefreshControl w moim UITableViewController (który znajduje się wewnątrz UINavigationController) i działa zgodnie z oczekiwaniami (tj. Pull down uruchamia prawidłowe zdarzenie). Jeśli jednak programowo wywołam beginRefreshing
metodę wystąpienia na kontrolce odświeżania, na przykład:
[self.refreshControl beginRefreshing];
Nic się nie dzieje. Powinien się animować i pokazywać przędzarkę. endRefreshing
Metoda działa prawidłowo, gdy zgłoszę, że po odświeżeniu.
Przygotowałem podstawowy projekt prototypowy z tym zachowaniem i działa on poprawnie, gdy mój UITableViewController jest dodawany bezpośrednio do głównego kontrolera widoku delegata aplikacji, np:
self.viewController = tableViewController;
self.window.rootViewController = self.viewController;
Ale jeśli tableViewController
najpierw dodam do UINavigationController, a następnie dodam kontroler nawigacji jako rootViewController
, beginRefreshing
metoda przestanie działać. Na przykład
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tableViewController];
self.viewController = navController;
self.window.rootViewController = self.viewController;
Mam wrażenie, że ma to coś wspólnego z zagnieżdżonymi hierarchiami widoków w kontrolerze nawigacyjnym, które nie działają dobrze z kontrolką odświeżającą - jakieś sugestie?
Dzięki
UITableViewController ma właściwość AutomaticAdjustsScrollViewInsets po iOS 7. Widok tabeli może już mieć contentOffset, zwykle (0, -64).
Tak więc właściwym sposobem wyświetlenia refreshControl po programowym rozpoczęciu odświeżania jest dodanie wysokości refreshControl do istniejącej zawartości contentOffset.
źródło
-64
lepiej użyć-self.topLayoutGuide.length
Oto rozszerzenie Swift korzystające ze strategii opisanych powyżej.
źródło
sendActionsForControlEvents(UIControlEvents.ValueChanged)
na końcu tej funkcji, w przeciwnym razie rzeczywista logika odświeżania nie zostanie uruchomiona.Żadna z pozostałych odpowiedzi nie działała dla mnie. Spowodowałyby, że przędzarka pokazywała się i obracała, ale sama akcja odświeżania nigdy by się nie wydarzyła. To działa:
Uwaga, w tym przykładzie użyto widoku tabeli, ale równie dobrze mógłby to być widok kolekcji.
źródło
SVPullToRefresh
, jak to programowo ściągnąć?[tableView triggerPullToRefresh];
” Zobacz: github.com/samvermette/ SVPullToRefreshscrollView.contentOffset = CGPoint(x: 0, y: scrollView.contentOffset.y - frame.height)
Wspomniane już podejście:
sprawi, że przędzarka będzie widoczna. Ale to się nie animowało. Zmieniłem tylko kolejność tych dwóch metod i wszystko działało:
źródło
Dla Swift 4 / 4.1
Mieszanka istniejących odpowiedzi działa za mnie:
Mam nadzieję że to pomoże!
źródło
Zobacz także to pytanie
UIRefreshControl nie wyświetla spiny podczas wywoływania funkcji beginRefreshing i contentOffset równej 0
Dla mnie wygląda to na błąd, ponieważ występuje tylko wtedy, gdy właściwość contentOffset tableView ma wartość 0
Naprawiłem to za pomocą następującego kodu (metoda dla UITableViewController):
źródło
beginRefreshing
, tylko że zmienia się jej stan. Jak widzę, ma to na celu zapobieżenie dwukrotnemu zainicjowaniu akcji odświeżania, tak aby programowo nazywany odświeżanie nadal działał, akcja zainicjowana przez użytkownika nie rozpocznie kolejnej.Oto rozszerzenie Swift 3 i nowsze, które pokazuje spinner, a także jego animację.
źródło
asyncAfter
właśnie sprawia, że animacja spinner działa (iOS 12.3 / Xcode 10.2)U mnie działa idealnie:
Swift 3:
źródło
W przypadku Swift 5 brakowało mi tylko połączenia
refreshControl.sendActions(.valueChanged)
. Zrobiłem rozszerzenie, aby było bardziej przejrzyste.źródło
Oprócz rozwiązania @Dymitry Shevchenko.
Znalazłem dobre obejście tego problemu. Możesz utworzyć rozszerzenie
UIRefreshControl
tej metody nadpisywania:Możesz użyć nowej klasy, ustawiając klasę niestandardową w Inspektorze tożsamości do sterowania odświeżaniem w programie Interface Builder.
źródło
Fort Swift 2.2+
źródło
Jeśli używasz Rxswift dla Swift 3.1, możesz użyć poniżej:
Ta praca dla Swift 3.1, iOS 10.
źródło
sendActions
wyzwalaczrx
sprawia, że ta odpowiedź jest związana z przypadkiem, gdyRxSwift
ktoś się zastanawia na pierwszy rzut okaself.tableView.setContentOffset(CGPoint(x:0, y:self.tableView.contentOffset.y - (refreshControl.frame.size.height)), animated: true)
testowane na Swift 5
użyj tego w
viewDidLoad()
źródło
Używam tej samej techniki, aby pokazać użytkownikowi wizualny znak „dane są aktualizacją”. Wynikowy użytkownik przeniesie aplikację z tła, a kanały / listy zostaną zaktualizowane za pomocą interfejsu użytkownika, tak jak użytkownicy pobierają tabele, aby odświeżyć się. Moja wersja zawiera 3 rzeczy
1) Kto wysyła „obudź się”
2) Obserwator w UIViewController
3) Protokół
źródło