Когда мои данные завершили загрузку и мой tableView был перезагружен, я вызываю endRefreshing на моем контроле обновления, затем он "перескакивает" из состояния загрузки и исчезает - как я могу реализовать плавную анимацию, которая удаляет элемент управления обновлением, когда он завершен?
UIRefreshControl endRefreshing не является гладким
Ответ 1
Я добавляю новый ответ, потому что единственный из них не очень точен в объяснении. И это, вероятно, будет слишком большим для комментариев.
Решение Halpo верное. Но указанная причина неверна.
Вызов -[NSObject (NSDelayedPerforming) performSelector:withObject:afterDelay:]
гарантирует, что вызов будет выполнен в следующей итерации runloop.
Так что это не работает, потому что есть небольшая задержка, но вы переходите к следующему циклу.
Фактически вы можете уменьшить задержку до 0.0
, и она все равно будет работать. Кроме того, возможно более правильное (с точки зрения использования объекта, предназначенного для достижения чего-то, а не лучшего результата).
Вот несколько фрагментов кода для этого:
// SOLUTION I
[[self tableView] reloadData];
[[self refreshControl] performSelector:@selector(endRefreshing) withObject:nil afterDelay:0.0];
// SOLUTION II (semantically correct)
[[self tableView] reloadData];
[[NSOperationQueue currentQueue] addOperationWithBlock:^{
[[self refreshControl] endRefreshing];
}];
// SOLUTION III (GCD)
dispatch_async(dispatch_get_main_queue(), ^{
[[self refreshControl] endRefreshing];
}];
ИЗМЕНИТЬ
Как отметил johann-fradj, вы также можете использовать GCD. Мне очень нравится GCD, но я думаю, что решение II наиболее описывает, что происходит. Кроме того, GCD не очень похож на Objective-C -ish, поэтому я лично предпочитаю использовать свое решение.
Ответ 2
Исправлена проблема - я добавил небольшую задержку для endRefresh после перезагрузки данных:
[self.tableView reloadData];
[self.refreshControl performSelector:@selector(endRefreshing) withObject:nil afterDelay:0.05];
Ответ 3
Решение Swift 4
tableView.reloadData()
if refreshControl?.isRefreshing == true {
DispatchQueue.main.async {
self.refreshControl?.endRefreshing()
}
}
Другие решения (задержка, использующая CATransaction,...) более сложны и не дают никакого видимого преимущества
Ответ 4
Попробуйте обернуть вызов endRefreshing()
в блоке анимации UIView:
Я столкнулся с этой проблемой. Для endRefreshing()
В документации указано:
UIView.animateWithDuration(0.5) {
self.refreshControl.endRefreshing()
}
В документации указано:
Если анимация также включена, элемент управления скрыт с помощью анимации.
Ответ 5
Одна из причин может заключаться в том, что вы обновляете представление таблицы после вызова endRefresh. Например, мои вызовы выглядели так:
[self.refreshControl beginRefreshing];
[self.network getThings:^(id things, NSError *error) {
[self.refreshControl endRefreshing];
if (error) {
...
} else {
self.things = things;
[self.tableView reloadData];
}
}];
Это плохо, потому что таблица обновляется, пока анимация endRefresh работает. Итак, код, сделанный правильно, выглядит так:
[self.refreshControl beginRefreshing];
[self.network getThings:^(id things, NSError *error) {
if (error) {
[self.refreshControl endRefreshing];
...
} else {
self.things = things;
[self.tableView reloadData];
[self.refreshControl endRefreshing];
}
}];
Ответ 6
Решением для меня было запустить refreshControl?.endRefreshing()
до вызова tableView.reloadData()
:
refreshControl?.endRefreshing()
tableView.reloadData()
Когда вызов к endRefreshing()
был после вызова к reloadData()
, TableView будет переходить при каждой перезагрузке данных.