Ответы:
Вы можете использовать setContentOffset:animated:
функцию UIScrollView для прокрутки к любой части представления содержимого. Вот некоторый код, который будет прокручиваться вниз, при условии, что ваш scrollView self.scrollView
:
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
Надеюсь, это поможет!
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
contentSize
ниже, чем bounds
. Так должно быть так:scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)
let bottomOffsetY = max(collectionView.contentSize.height - collectionView.bounds.height + collectionView.contentInset.bottom, 0)
Быстрая версия принятого ответа для легкого копирования копии:
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height)
scrollView.setContentOffset(bottomOffset, animated: true)
Самое простое решение:
[scrollview scrollRectToVisible:CGRectMake(scrollview.contentSize.width - 1,scrollview.contentSize.height - 1, 1, 1) animated:YES];
Просто улучшение существующего ответа.
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
Он также заботится о нижней вставке (если вы используете ее для настройки вида прокрутки, когда клавиатура видна)
Быстрая реализация:
extension UIScrollView {
func scrollToBottom(animated: Bool) {
if self.contentSize.height < self.bounds.size.height { return }
let bottomOffset = CGPoint(x: 0, y: self.contentSize.height - self.bounds.size.height)
self.setContentOffset(bottomOffset, animated: animated)
}
}
используй это:
yourScrollview.scrollToBottom(animated: true)
Неверно задано смещение содержимого по высоте размера содержимого: оно прокручивает нижнюю часть содержимого до верхней части представления прокрутки и, таким образом, скрывается.
Правильное решение состоит в том, чтобы прокрутить нижнюю часть содержимого до нижней части представления прокрутки, например, так ( sv
это UIScrollView):
CGSize csz = sv.contentSize;
CGSize bsz = sv.bounds.size;
if (sv.contentOffset.y + bsz.height > csz.height) {
[sv setContentOffset:CGPointMake(sv.contentOffset.x,
csz.height - bsz.height)
animated:YES];
}
if (sv.contentOffset.y + csz.height > bsz.height) {
?
setContentOffset:
команда, которая важна.
Решение Swift 2.2 с contentInset
учетом
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
Это должно быть в расширении
extension UIScrollView {
func scrollToBottom() {
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
setContentOffset(bottomOffset, animated: true)
}
}
Обратите внимание, что вы можете проверить, если bottomOffset.y > 0
перед прокруткой
Что если contentSize
ниже чемbounds
?
Для Свифта это:
scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)
Пролистать наверх
- CGPoint topOffset = CGPointMake(0, 0);
- [scrollView setContentOffset:topOffset animated:YES];
Прокрутить до низа
- CGPoint bottomOffset = CGPointMake(0, scrollView.contentSize.height - self.scrollView.bounds.size.height);
- [scrollView setContentOffset:bottomOffset animated:YES];
Я также нашел другой полезный способ сделать это в случае, если вы используете UITableview (который является подклассом UIScrollView):
[(UITableView *)self.view scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
Использование setContentOffset:animated:
функции UIScrollView для прокрутки вниз в Swift.
let bottomOffset : CGPoint = CGPointMake(0, scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
Похоже, что все ответы здесь не приняли во внимание безопасную область. Начиная с iOS 11, в iPhone X появилась безопасная зона. Это может повлиять на scrollViewcontentInset
.
Для iOS 11 и выше, чтобы правильно прокрутить до конца с включенным содержимым. Вы должны использовать adjustedContentInset
вместо contentInset
. Проверьте этот код:
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.height + scrollView.adjustedContentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.adjustedContentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
contentOffset.x
):extension UIScrollView {
func scrollsToBottom(animated: Bool) {
let bottomOffset = CGPoint(x: contentOffset.x,
y: contentSize.height - bounds.height + adjustedContentInset.bottom)
setContentOffset(bottomOffset, animated: animated)
}
}
Ссылки:
Swift:
Вы можете использовать расширение как это:
extension UIScrollView {
func scrollsToBottom(animated: Bool) {
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height)
setContentOffset(bottomOffset, animated: animated)
}
}
Использование:
scrollView.scrollsToBottom(animated: true)
Категория на помощь!
Добавьте это к общему заголовку утилиты где-нибудь:
@interface UIScrollView (ScrollToBottom)
- (void)scrollToBottomAnimated:(BOOL)animated;
@end
А затем к этой реализации утилиты:
@implementation UIScrollView(ScrollToBottom)
- (void)scrollToBottomAnimated:(BOOL)animated
{
CGPoint bottomOffset = CGPointMake(0, self.contentSize.height - self.bounds.size.height);
[self setContentOffset:bottomOffset animated:animated];
}
@end
Затем реализуйте его, где хотите, например:
[[myWebView scrollView] scrollToBottomAnimated:YES];
Для горизонтального ScrollView
Если я вам нравлюсь, у вас есть Horizontal ScrollView и вы хотите прокрутить его до конца (в моем случае до самого правого), вам нужно изменить некоторые части принятого ответа:
Objective-C
CGPoint rightOffset = CGPointMake(self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, 0 );
[self.scrollView setContentOffset:rightOffset animated:YES];
стриж
let rightOffset: CGPoint = CGPoint(x: self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, y: 0)
self.scrollView.setContentOffset(rightOffset, animated: true)
Если вы как-то измените scrollView contentSize (например, добавьте что-то в stackView, которое находится внутри scrollView), вы должны вызватьscrollView.layoutIfNeeded()
перед прокруткой, в противном случае он ничего не делает.
Пример:
scrollView.layoutIfNeeded()
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
if(bottomOffset.y > 0) {
scrollView.setContentOffset(bottomOffset, animated: true)
}
Хороший способ обеспечить видимость нижней части вашего контента - использовать формулу:
contentOffsetY = MIN(0, contentHeight - boundsHeight)
Это гарантирует, что нижний край вашего контента всегда находится у нижнего края представления или над ним. MIN(0, ...)
Требуется потому , что UITableView
(и , вероятно UIScrollView
) обеспечивает , contentOffsetY >= 0
когда пользователь пытается прокручивать заметно щелкать contentOffsetY = 0
. Это выглядит довольно странно для пользователя.
Код для реализации этого:
UIScrollView scrollView = ...;
CGSize contentSize = scrollView.contentSize;
CGSize boundsSize = scrollView.bounds.size;
if (contentSize.height > boundsSize.height)
{
CGPoint contentOffset = scrollView.contentOffset;
contentOffset.y = contentSize.height - boundsSize.height;
[scrollView setContentOffset:contentOffset animated:YES];
}
Если вам не нужна анимация, это работает:
[self.scrollView setContentOffset:CGPointMake(0, CGFLOAT_MAX) animated:NO];
В то время как Matt
решение кажется мне правильным, необходимо учитывать также вкладку представления коллекции, если она была настроена.
Адаптированный код будет:
CGSize csz = sv.contentSize;
CGSize bsz = sv.bounds.size;
NSInteger bottomInset = sv.contentInset.bottom;
if (sv.contentOffset.y + bsz.height + bottomInset > csz.height) {
[sv setContentOffset:CGPointMake(sv.contentOffset.x,
csz.height - bsz.height + bottomInset)
animated:YES];
}
Решение прокрутить до последнего элемента таблицы.
Свифт 3:
if self.items.count > 0 {
self.tableView.scrollToRow(at: IndexPath.init(row: self.items.count - 1, section: 0), at: UITableViewScrollPosition.bottom, animated: true)
}
Не работает для меня, когда я пытался использовать его в UITableViewController
на self.tableView
(iOS 4.1)
, после добавленияfooterView
. Он прокручивается за границы, показывая черный экран.
Альтернативное решение:
CGFloat height = self.tableView.contentSize.height;
[self.tableView setTableFooterView: myFooterView];
[self.tableView reloadData];
CGFloat delta = self.tableView.contentSize.height - height;
CGPoint offset = [self.tableView contentOffset];
offset.y += delta;
[self.tableView setContentOffset: offset animated: YES];
CGFloat yOffset = scrollView.contentOffset.y;
CGFloat height = scrollView.frame.size.height;
CGFloat contentHeight = scrollView.contentSize.height;
CGFloat distance = (contentHeight - height) - yOffset;
if(distance < 0)
{
return ;
}
CGPoint offset = scrollView.contentOffset;
offset.y += distance;
[scrollView setContentOffset:offset animated:YES];
Я обнаружил, что contentSize
это на самом деле не отражает фактический размер текста, поэтому при попытке прокрутки вниз он будет немного отключен. Лучший способ для определения фактического размера контента на самом деле использовать в NSLayoutManager
«S usedRectForTextContainer:
метода:
UITextView *textView;
CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size;
Чтобы определить, сколько текста на самом деле отображается в UITextView
, вы можете рассчитать его, вычтя вставки текстового контейнера из высоты рамки.
UITextView *textView;
UIEdgeInsets textInsets = textView.textContainerInset;
CGFloat textViewHeight = textView.frame.size.height - textInsets.top - textInsets.bottom;
Тогда становится легко прокручиваться:
// if you want scroll animation, use contentOffset
UITextView *textView;
textView.contentOffset = CGPointMake(textView.contentOffset.x, textSize - textViewHeight);
// if you don't want scroll animation
CGRect scrollBounds = textView.bounds;
scrollBounds.origin = CGPointMake(textView.contentOffset.x, textSize - textViewHeight);
textView.bounds = scrollBounds;
Некоторые цифры для справки о том, что разные размеры представляют для пустого UITextView
.
textView.frame.size = (width=246, height=50)
textSize = (width=10, height=16.701999999999998)
textView.contentSize = (width=246, height=33)
textView.textContainerInset = (top=8, left=0, bottom=8, right=0)
Расширьте UIScrollView, чтобы добавить метод scrollToBottom:
extension UIScrollView {
func scrollToBottom(animated:Bool) {
let offset = self.contentSize.height - self.visibleSize.height
if offset > self.contentOffset.y {
self.setContentOffset(CGPoint(x: 0, y: offset), animated: animated)
}
}
}
Версия Xamarin.iOS для UICollectionView
принятого ответа для простоты копирования и вставки
var bottomOffset = new CGPoint (0, CollectionView.ContentSize.Height - CollectionView.Frame.Size.Height + CollectionView.ContentInset.Bottom);
CollectionView.SetContentOffset (bottomOffset, false);