UIRefreshControl без UITableViewController
просто любопытно, как это не сразу кажется возможным, но есть ли хитрый способ использовать новый iOS 6 UIRefreshControl класс без использования UITableViewController подкласс?
Я часто использую UIViewController С UITableView subview и соответствовать UITableViewDataSource и UITableViewDelegate вместо UITableViewController вчистую.
12 ответов:
по интуиции, и на основе вдохновения DrummerB, я попытался просто добавить
UIRefreshControlэкземпляр в качестве подвида для myUITableView. И это волшебно просто работает!UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged]; [self.myTableView addSubview:refreshControl];добавляет
UIRefreshControlнад вашим представлением таблицы и работает, как ожидалось, без необходимости использоватьUITableViewController:)
EDIT: это выше все еще работает, но, как некоторые указали, есть небольшое "заикание" при добавлении UIRefreshControl таким образом. Решение это создать UITableViewController, а затем установить UIRefreshControl и UITableView к этому, т. е.:
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;
чтобы устранить заикание, вызванное принятым ответом, вы можете назначить свой
UITableViewдо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:
добавлять
UIRefreshControlСUITableViewControllerбез заикания и сохранить хорошую анимацию после обновления данных на tableview.UIRefreshControl *refreshControl = [UIRefreshControl new]; [refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged]; [self.theTableView addSubview:refreshControl]; [self.theTableView sendSubviewToBack:refreshControl];позже при обработке обновленных данных...
- (void)handleRefresh:(UIRefreshControl *)refreshControl { [self.theTableView reloadData]; [self.theTableView layoutIfNeeded]; [refreshControl endRefreshing]; }
то, что вы хотели бы попробовать, это использовать вид контейнера внутри ViewController вы используете. вы можете определить чистый подкласс UITableViewController с выделенным tableview и поместить его в ViewController.
Ну UIRefreshControl-это подкласс UIView, поэтому вы можете использовать его самостоятельно. Я не уверен, хотя, как это делает себя. Рендеринг может просто зависеть от кадра, но он также может полагаться на UIScrollView или UITableViewController.
в любом случае, это будет скорее Хак, чем элегантное решение. Я рекомендую вам заглянуть в один из доступных клонов 3rd party или написать свой собственный.
попробуйте отложить вызов refreshControl
-endRefreshспособ на доли секунды после TableView для загружает его содержимое, либо с помощьюили ГКД dispatch_after.Я создал категорию на UIRefreshControl для этого:
@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я протестировал его, и это также работает на представлениях коллекции. Я заметил, что задержка так мала, как 0.01 секунд достаточно:
// My data refresh process here while the refresh control 'isRefreshing' [self.tableView reloadData]; [self.refreshControl endRefreshingAfterDelay:.01];
IOS 10 Swift 3.0
это просто
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 } }если вы хотите узнать о iOS 10 UIRefreshControl читать здесь.
добавление элемента управления refresh в качестве подвида создает пустое пространство над заголовками разделов.
вместо этого я встроил UITableViewController в мой UIViewController, а затем изменил мой
tableViewсвойство указывать на встроенный, и альт! Минимальные изменения кода. : -)действия:
- создайте новый UITableViewController в раскадровке и вставьте его в свой оригинальный UIViewController
- заменить
@IBOutlet weak var tableView: UITableView!С одним из недавно встроенный UITableViewController, как показано ниже
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 } ... }
Для Swift 2.2 .
сначала сделайте UIRefreshControl ().
var refreshControl : UIRefreshControl!в вашем методе viewDidLoad() добавить:
refreshControl = UIRefreshControl() refreshControl.attributedTitle = NSAttributedString(string: "Refreshing..") refreshControl.addTarget(self, action: #selector(YourUIViewController.refresh(_:)), forControlEvents: UIControlEvents.ValueChanged) self.tableView.addSubview(refreshControl)и сделать функцию обновления
func refresh(refreshControl: UIRefreshControl) { // do something ... // reload tableView self.tableView.reloadData() // End refreshing refreshControl.endRefreshing() }
вот еще одно решение, которое немного отличается.
мне пришлось использовать его из-за некоторых проблем иерархии представлений, которые у меня были: я создавал некоторые функции, которые требовали передачи представлений в разные места иерархии представлений, которые нарушались при использовании табличного представления UITableViewController b/c tableView-это корневое представление UITableViewController (self.view) и не просто обычный вид, он создал несогласованные иерархии контроллера / представления и вызвал крушение.
в основном создайте свой собственный подкласс UITableViewController и переопределите loadView для назначения self.просмотрите другое представление и переопределите свойство tableView, чтобы вернуть отдельный tableview.
например:
@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в сочетании с решением Келлера это будет более надежным в том смысле, что tableView теперь является обычным представлением, а не корневым представлением VC, и будет более устойчивым к изменению иерархий представлений. Пример его использования это образом:
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;есть еще одно возможное применение для этого:
Так как подклассы таким образом отделяет себя.вид из себя.tableView, теперь можно использовать этот UITableViewController как более обычный контроллер и добавлять другие подвиды к себе.просмотр без странностей добавления подвидов в UITableView, поэтому можно рассмотреть возможность сделать их контроллеры представления непосредственно подклассом UITableViewController вместо того, чтобы иметь UITableViewController дети.
некоторые вещи, чтобы наблюдать за:
Так как мы переопределяем свойство tableView без вызова super, могут быть некоторые вещи, которые следует остерегаться и должны обрабатывать там, где это необходимо. Например, установка tableview в моем примере выше не добавит tableview к себе.просмотр и не установить кадр, который вы можете сделать. Кроме того, в этой реализации нет табличного представления по умолчанию, данного вам при создании экземпляра класса, что также является чем-то, что вы может рассмотреть возможность добавления. Я не включаю его здесь, потому что это случай за случаем, и это решение действительно хорошо подходит к решению Келлера.
попробуйте это,
вышеуказанные решения прекрасны, но tableView.refreshControl доступен только для UITableViewController, до iOS 9.x и поставляется в UITableView от iOS 10.х года.
написано на 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)
первое предложение Келлера вызывает странную ошибку в iOS 7, где вставка таблицы увеличивается после повторного появления контроллера вида. Переход ко второму ответу, используя uitableviewcontroller, исправил все для меня.
оказывается, вы можете использовать следующее При использовании UIViewController с UITableView subview и соответствовать UITableViewDataSource и UITableViewDelegate:
self.refreshControl = [[UIRefreshControl alloc]init]; [self.refreshControl addTarget:self action:@selector(refresh:) forControlEvents:UIControlEventValueChanged];



Comments