Как сделать прокрутку UIScrollView наверх?
Как сделать прокрутку UIScrollView наверх?
Ответы:
[self.scrollView setContentOffset:
CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];
[self.scrollView setContentOffset:CGPointZero animated:YES];
или если вы хотите сохранить положение горизонтальной прокрутки и просто сбросить положение по вертикали:
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, 0)
animated:YES];
[scrollView setContentOffset:CGPointMake(0, -scrollView.contentInset.top) animated:YES];
Это работает в iOS 6 и 7
[scrollView setContentOffset:CGPointMake(0, scrollView.contentSize.height-scrollView.frame.size.height) animated:YES];
Вот расширение Swift, которое облегчает:
extension UIScrollView {
func scrollToTop() {
let desiredOffset = CGPoint(x: 0, y: -contentInset.top)
setContentOffset(desiredOffset, animated: true)
}
}
Использование:
myScrollView.scrollToTop()
попробуй поработай с новым adjustedContentInset
.
Например (прокрутите вверх):
var offset = CGPoint(
x: -scrollView.contentInset.left,
y: -scrollView.contentInset.top)
if #available(iOS 11.0, *) {
offset = CGPoint(
x: -scrollView.adjustedContentInset.left,
y: -scrollView.adjustedContentInset.top)
}
scrollView.setContentOffset(offset, animated: true)
Даже если вы используете
prefersLargeTitles
иsafe area
т. Д.
Для Swift 4
scrollView.setContentOffset(.zero, animated: true)
использование setContentOffset:animated:
[scrollView setContentOffset:CGPointZero animated:YES];
В iOS7 у меня были проблемы с получением определенного вида прокрутки для перехода наверх, который работал в iOS6, и использовал это, чтобы настроить вид прокрутки для перехода наверх.
[self.myScroller scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
Версия Swift 3.0.1 от Rob Mayoff :
self.scrollView.setContentOffset(
CGPoint(x: 0,y: -self.scrollView.contentInset.top),
animated: true)
Чтобы полностью копировать поведение строки состояния scrollToTop, нам нужно не только установить contentOffset, но и убедиться, что отображаются scrollIndicators. В противном случае пользователь может быстро потеряться.
Единственный публичный способ сделать это flashScrollIndicators
. К сожалению, вызов его один раз после установки contentOffset не имеет никакого эффекта, потому что он сбрасывается немедленно. Я обнаружил, что это работает, когда делает вспышку каждый раз в scrollViewDidScroll:
.
// define arbitrary tag number in a global constants or in the .pch file
#define SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG 19291
- (void)scrollContentToTop {
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];
self.scrollView.tag = SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.scrollView.tag = 0;
});
}
В вашем UIScrollViewDelegate (или UITable / UICollectionViewDelegate) реализуйте это:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.tag == SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG) {
[scrollView flashScrollIndicators];
}
}
Задержка скрытия немного короче по сравнению с поведением scrollToTop в строке состояния, но все равно выглядит хорошо.
Обратите внимание, что я злоупотребляю тэгом представления для сообщения о состоянии «isScrollingToTop», потому что мне это нужно через контроллеры вида. Если вы используете теги для чего-то другого, вы можете заменить это на iVar или свойство.
Я думаю, что у меня есть ответ, который должен быть полностью совместим с iOS 11, а также с предыдущими версиями (для вертикальной прокрутки)
При этом учитывается новое значение selectedContentInset, а также учитывается дополнительное смещение, необходимое при включении prefersLargeTitles на навигационной панели, которое, по-видимому, требует дополнительного смещения в 52 пикселя поверх значения по умолчанию.
Это было немного сложно, потому чтоsetContentInset изменяется в зависимости от состояния titleBar (большой заголовок против маленького заголовка), поэтому мне нужно было проверить и посмотреть, какова была высота titleBar, и не применять смещение 52px, если оно уже находится в большом состоянии. Не удалось найти какой-либо другой метод для проверки состояния navigationBar, поэтому, если у кого-то есть лучший вариант, чем видеть, является ли высота> 44,0, я бы хотел услышать его
func scrollToTop(_ scrollView: UIScrollView, animated: Bool = true) {
if #available(iOS 11.0, *) {
let expandedBar = (navigationController?.navigationBar.frame.height ?? 64.0 > 44.0)
let largeTitles = (navigationController?.navigationBar.prefersLargeTitles) ?? false
let offset: CGFloat = (largeTitles && !expandedBar) ? 52: 0
scrollView.setContentOffset(CGPoint(x: 0, y: -(scrollView.adjustedContentInset.top + offset)), animated: animated)
} else {
scrollView.setContentOffset(CGPoint(x: 0, y: -scrollView.contentInset.top), animated: animated)
}
}
Вдохновленный решением Якуба
Это очень распространено, когда ваша панель навигации перекрывает небольшую часть содержимого scrollView и выглядит так, будто контент начинается не сверху. Для исправления я сделал 2 вещи:
Прокрутка к началу для UITableViewController
, UICollectionViewController
или любого UIViewController
имеющейUIScrollView
extension UIViewController {
func scrollToTop(animated: Bool) {
if let tv = self as? UITableViewController {
tv.tableView.setContentOffset(CGPoint.zero, animated: animated)
} else if let cv = self as? UICollectionViewController{
cv.collectionView?.setContentOffset(CGPoint.zero, animated: animated)
} else {
for v in view.subviews {
if let sv = v as? UIScrollView {
sv.setContentOffset(CGPoint.zero, animated: animated)
}
}
}
}
}
В SWIFT 5 Просто установите смещение контента на ноль
scrollView.setContentOffset(CGPoint.zero, animated: true)
Я перепробовал все способы. Но у меня ничего не получалось. Наконец-то мне это понравилось.
Я добавил self.view .addSubview(self.scroll)
строку кода в viewDidLoad. После начала настройки рамки для просмотра с прокруткой и добавления компонентов для просмотра с прокруткой.
Это сработало для меня.
Убедитесь, что вы добавили self.view .addSubview(self.scroll)
строку в начале. Затем вы можете добавить элементы пользовательского интерфейса.
UIScrollView
contentInset
, к сожалению.[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];
делает работу для меня