UIRefreshControl bez UITableViewController
Tak z ciekawości, ponieważ nie od razu wydaje się to możliwe, ale czy istnieje sprytny sposób na wykorzystanie nowej klasy iOS 6 UIRefreshControl
bez użycia podklasy UITableViewController
?
Często używam UIViewController
z UITableView
subview i zgodne z UITableViewDataSource
i UITableViewDelegate
zamiast używać UITableViewController
wprost.
12 answers
Na przeczucie i na podstawie inspiracji Drummerba, próbowałem po prostu dodać instancję UIRefreshControl
jako subview do mojego UITableView
. I to magicznie po prostu działa!
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
[self.myTableView addSubview:refreshControl];
To dodaje UIRefreshControl
powyżej widoku tabeli i działa zgodnie z oczekiwaniami bez konieczności używania UITableViewController
:)
EDIT: powyższe nadal działa, ale jak zauważyli niektórzy, podczas dodawania interfejsu UIRefreshControl w ten sposób występuje lekkie "zacinanie się". Rozwiązaniem jest utworzenie instancji UITableViewController, a następnie ustawienie Twój UIRefreshControl i UITableView do tego, czyli:
UITableViewController *tableViewController = [[UITableViewController alloc] init];
tableViewController.tableView = self.myTableView;
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(getConnections) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-05 00:46:48
Aby wyeliminować jąkanie, które jest spowodowane zaakceptowaną odpowiedzią, możesz przypisać UITableView
do UITableViewController
.
_tableViewController = [[UITableViewController alloc]initWithStyle:UITableViewStylePlain];
[self addChildViewController:_tableViewController];
_tableViewController.refreshControl = [UIRefreshControl new];
[_tableViewController.refreshControl addTarget:self action:@selector(loadStream) forControlEvents:UIControlEventValueChanged];
_theTableView = _tableViewController.tableView;
EDIT:
Sposób na dodanie UIRefreshControl
Bez UITableViewController
bez jąkania i zachowanie ładnej animacji po odświeżeniu danych w widoku tableview.
UIRefreshControl *refreshControl = [UIRefreshControl new];
[refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged];
[self.theTableView addSubview:refreshControl];
[self.theTableView sendSubviewToBack:refreshControl];
Później podczas obsługi odświeżonych danych...
- (void)handleRefresh:(UIRefreshControl *)refreshControl {
[self.theTableView reloadData];
[self.theTableView layoutIfNeeded];
[refreshControl endRefreshing];
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-06 18:29:21
Spróbowałbyś użyć widoku kontenera wewnątrz Viewcontrollera, którego używasz. możesz zdefiniować czystą podklasę UITableViewController za pomocą dedykowanego tableview i umieścić ją w ViewController.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-25 21:09:31
Cóż UIRefreshControl jest podklasą UIView, więc możesz jej używać samodzielnie. Nie jestem pewien, jak to się przedstawia. Renderowanie może po prostu zależeć od ramki, ale może również polegać na UIScrollView lub UITableViewController.
Tak czy inaczej, będzie to bardziej hack niż eleganckie rozwiązanie. Polecam zajrzeć do jednego z dostępnych klonów 3rd party lub napisać swój własne.
ODRefreshControl
SlimeRefresh
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-19 15:38:46
Spróbuj opóźnić wywołanie metody refreshControl -endRefresh
o ułamek sekundy po przeładowaniu zawartości tableView, używając NSObject -performSelector:withObject:afterDelay:
lub GCD dispatch_after
.
Utworzyłem kategorię na UIRefreshControl dla tego:
@implementation UIRefreshControl (Delay)
- (void)endRefreshingAfterDelay:(NSTimeInterval)delay {
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[self endRefreshing];
});
}
@end
Przetestowałem go i działa to również na widokach kolekcji. Zauważyłem, że opóźnienie tak małe jak 0.01 sekundy wystarczy:
// My data refresh process here while the refresh control 'isRefreshing'
[self.tableView reloadData];
[self.refreshControl endRefreshingAfterDelay:.01];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-03 04:48:41
IOS 10 Swift 3.0
It ' s simple
import UIKit
class ViewControllerA: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var myTableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
myTableView.delegate = self
myTableView.dataSource = self
if #available(iOS 10.0, *) {
let refreshControl = UIRefreshControl()
let title = NSLocalizedString("PullToRefresh", comment: "Pull to refresh")
refreshControl.attributedTitle = NSAttributedString(string: title)
refreshControl.addTarget(self,
action: #selector(refreshOptions(sender:)),
for: .valueChanged)
myTableView.refreshControl = refreshControl
}
}
@objc private func refreshOptions(sender: UIRefreshControl) {
// Perform actions to refresh the content
// ...
// and then dismiss the control
sender.endRefreshing()
}
// MARK: - Table view data source
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 12
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
cell.textLabel?.text = "Cell \(String(indexPath.row))"
return cell
}
}
Jeśli chcesz dowiedzieć się więcej o IOS 10 UIRefreshControl przeczytaj Proszę..
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-22 15:49:46
Dodanie kontrolki odświeżania jako podglądu podrzędnego tworzy pustą przestrzeń nad nagłówkami sekcji.
Zamiast tego, wbudowałem UITableViewController do mojego UIViewController, a następnie zmieniłem moją Właściwość tableView
, aby wskazywała na wbudowaną i viola! Minimalne zmiany kodu. :-)
Kroki:
- Utwórz nowy UITableViewController w Storyboard i osadzić go w oryginalnym UIViewController
- Zastąp
@IBOutlet weak var tableView: UITableView!
tym z nowo wbudowanego kontrolera UITableViewController, jak pokazano poniżej
class MyViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
let tableViewController = self.childViewControllers.first as! UITableViewController
tableView = tableViewController.tableView
tableView.dataSource = self
tableView.delegate = self
// Now we can (properly) add the refresh control
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: "handleRefresh:", forControlEvents: .ValueChanged)
tableViewController.refreshControl = refreshControl
}
...
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-01 07:33:38
Dla Swift 2.2 .
Najpierw Utwórz UIRefreshControl() .
var refreshControl : UIRefreshControl!
W metodzie viewDidLoad () dodaj:
refreshControl = UIRefreshControl()
refreshControl.attributedTitle = NSAttributedString(string: "Refreshing..")
refreshControl.addTarget(self, action: #selector(YourUIViewController.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged)
self.tableView.addSubview(refreshControl)
And make refresh function
func refresh(refreshControl: UIRefreshControl) {
// do something ...
// reload tableView
self.tableView.reloadData()
// End refreshing
refreshControl.endRefreshing()
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-17 20:06:31
Oto inne rozwiązanie, które jest trochę inne.
Musiałem go użyć z powodu pewnych problemów z hierarchią widoków: tworzyłem funkcjonalność, która wymagała przekazywania widoków do różnych miejsc w hierarchii widoków, co złamało się podczas używania tableview UITableView kontrolera b / c tableView jest głównym widokiem UITableView kontrolera (self.widok), a nie tylko zwykły widok, stworzył niespójne hierarchie kontrolera / widoku i spowodował awarię.
Zasadniczo utwórz własną podklasę UITableViewController i nadpisaj loadView, aby przypisać self.wyświetl inny widok i Nadpisz właściwość tableView, aby zwrócić oddzielny widok tableview.
Na przykład:
@interface MyTableVC : UITableViewController
@end
@interface MyTableVC ()
@property (nonatomic, strong) UITableView *separateTableView;
@end
@implementation MyTableVC
- (void)loadView {
self.view = [[UIView alloc] initWithFrame:CGRectZero];
}
- (UITableView *)tableView {
return self.separateTableView;
}
- (void)setTableView:(UITableView *)tableView {
self.separateTableView = tableView;
}
@end
W połączeniu z rozwiązaniem Kellera będzie to bardziej wytrzymałe w tym sensie, że tableView jest teraz regularnym widokiem, a nie głównym widokiem VC, i będzie bardziej odporne na zmiany hierarchii widoków. Przykład użycia go w ten sposób:
MyTableVC *tableViewController = [[MyTableVC alloc] init];
tableViewController.tableView = self.myTableView;
self.refreshControl = [[UIRefreshControl alloc] init];
[self.refreshControl addTarget:self action:@selector(getConnections) forControlEvents:UIControlEventValueChanged];
tableViewController.refreshControl = self.refreshControl;
Istnieje inne możliwe zastosowanie dla to:
Ponieważ podklasowanie w ten sposób oddziela ja.widok z siebie.tableView, możliwe jest teraz używanie tego kontrolera UITableViewController jako bardziej zwykłego kontrolera i dodawanie innych podglądów do self.Widok bez osobliwości dodawania podwidi do UITableView, więc można rozważyć uczynienie ich kontrolerów widoku bezpośrednio podklasą UITableViewController zamiast mieć dzieci uitableviewcontroller.
Niektóre rzeczy, na które warto uważać:
Ponieważ nadpisujemy widok tabeli nieruchomość bez wywoływania super, mogą być pewne rzeczy, na które należy uważać i powinny obsługiwać w razie potrzeby. Na przykład ustawienie widoku tableview w powyższym przykładzie nie spowoduje dodania widoku tableview do self.Wyświetl i nie ustawiaj ramki, którą chcesz zrobić. Ponadto, w tej implementacji nie ma domyślnego widoku tableView, gdy klasa jest tworzona jako instancja, co jest również czymś, co możesz rozważyć dodanie. Nie zamieszczam go tutaj, bo tak jest w każdym przypadku, a to rozwiązanie faktycznie dobrze pasuje z rozwiązaniem Kellera.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-08 21:48:06
Spróbuj tego,
Powyższe rozwiązania są w porządku, ale tableView.refreshControl jest dostępny tylko dla UITableViewController, do iOS 9.x i jest dostępny w widoku UITableView z iOS 10.XD
Napisane w Swift 3-
let refreshControl = UIRefreshControl()
refreshControl.addTarget(self, action: #selector(FeedViewController.loadNewData), for: UIControlEvents.valueChanged)
// Fix for the RefreshControl Not appearing in background
tableView?.addSubview(refreshControl)
tableView.sendSubview(toBack: refreshControl)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-12 05:12:07
Pierwsza sugestia Kellera powoduje dziwny błąd w iOS 7, gdzie wstawka tabeli jest zwiększana po ponownym pojawieniu się kontrolera widoku. Zmiana na drugą odpowiedź, za pomocą kontrolera uitableviewcontroller, naprawiła dla mnie pewne rzeczy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-25 11:13:01
Okazuje się, że podczas używania kontrolera UIViewController z subview UITableView i zgodnego z UITableViewDataSource i UITableViewDelegate można użyć następujących elementów:
self.refreshControl = [[UIRefreshControl alloc]init];
[self.refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-13 19:04:30