Як зробити прокрутку 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];
Версія відповіді Robi Mayoff Swift 3.0.1 :
self.scrollView.setContentOffset(
CGPoint(x: 0,y: -self.scrollView.contentInset.top),
animated: true)
Для повного тиражування поведінки рядка статусу scrollToTop нам потрібно не тільки встановити contentOffset, але й хочемо переконатися, що відображаються покажчики scrollIndicator. Інакше користувач може швидко загубитися.
Єдиний публічний метод досягти цього - це 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, а також попередніми версіями (для вертикальної прокрутки)
При цьому береться до уваги нову adjustedContentInset , а також рахунки за додаткове зміщення потрібно , коли prefersLargeTitles включена на Панель навігації , яка , як видається , вимагає додаткового 52px зміщення поверх будь за замовчуванням
Це було трохи хитро, тому що customContentInset змінюється залежно від стану titleBar (великий заголовок проти невеликого заголовка), тому мені потрібно було перевірити і побачити, яка висота titleBar, а не застосувати зміщення 52px, якщо воно вже є у великому стані. Не вдалося знайти жодного іншого способу перевірити стан навігації, тому якщо хтось має кращий варіант, ніж бачити, чи висота> 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];
робить роботу для мене