#iphone #uiscrollviewdelegate
#iPhone #uiscrollviewdelegate
Вопрос:
Я знаю, что в документации Apple есть следующий метод делегирования:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView; // called when scroll view grinds to a halt
Однако это не обязательно означает, что вы находитесь внизу. Потому что, если вы используете палец, немного прокручиваете, затем это замедляется, но на самом деле вы не находитесь в нижней части экрана прокрутки, тогда он все равно вызывается. Я в основном хочу, чтобы стрелка показывала, что в моем режиме прокрутки больше данных, а затем исчезала, когда вы находитесь внизу (например, когда она отскакивает). Спасибо.
Ответ №1:
Я думаю, что вы могли бы сделать, это проверить, находится ли ваша contentOffset
точка внизу contentSize
. Таким образом, вы, вероятно, могли бы сделать что-то вроде:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
float bottomEdge = scrollView.contentOffset.y scrollView.frame.size.height;
if (bottomEdge >= scrollView.contentSize.height) {
// we are at the end
}
}
Вероятно, вам также понадобится отрицательный регистр, чтобы отобразить ваш индикатор, когда пользователь прокручивает его обратно. Возможно, вы также захотите добавить к этому некоторые дополнения, чтобы, например, вы могли скрыть индикатор, когда пользователь находится в нижней части, но не совсем внизу.
Комментарии:
1. Лучшее решение, но я бы поместил его в — (void)scrollViewDidScroll:(UIScrollView *)ScrollView{} вместо этого
2. @MobileMon прав, его следует использовать в
scrollViewDidScroll
методе.3. Как раз те строки, которые я искал. Работает и с UICollectionView.
4. Если вы готовы поместить свою логику внутрь
scrollViewDidScroll
, вам нужно разработать какой-нибудь защитный флаг, который предотвратит запуск вашей логики миллион раз. Это потому, что у вас есть>=
там, и оно будет успешно попадать внутрьif
предложения миллион раз, когда ваше табличное представление отскакивает. Гораздо лучше наблюдать за окончанием замедления, поскольку оно вызывается после завершения отскока5. scrollViewDidEndDecelerating не запускается, если я вызываю: cv.scrollToBottom()
Ответ №2:
Итак, если вы хотите это в swift, вот и все:
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
if (scrollView.contentOffset.y >= (scrollView.contentSize.height - scrollView.frame.size.height)) {
//reach bottom
}
if (scrollView.contentOffset.y < 0){
//reach top
}
if (scrollView.contentOffset.y >= 0 amp;amp; scrollView.contentOffset.y < (scrollView.contentSize.height - scrollView.frame.size.height)){
//not top and not bottom
}
}
Ответ №3:
Я думаю, что ответ @bensnider правильный, но не exart. По этим двум причинам
1. - (void)scrollViewDidScroll:(UIScrollView *)scrollView{}
Этот метод будет вызываться непрерывно, если мы проверяем наличие if (bottomEdge >= scrollView.contentSize.height)
2 . В этом случае, если мы перейдем к ==
проверке, это условие также будет действовать два раза.
- (i) когда мы будем прокручивать вверх, когда конец прокрутки касается нижнего края
- (ii) Когда scrollview отскакивает назад, чтобы сохранить свое собственное положение
Я чувствую, что это более точно.
В очень немногих случаях эта кодировка действительна и для двух раз. Но пользователь не столкнется с этим.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (scrollView.contentOffset.y == roundf(scrollView.contentSize.height-scrollView.frame.size.height)) {
NSLog(@"we are at the endddd");
//Call your function here...
}
}
Комментарии:
1. Да, это должен был быть принятый ответ. Кроме того, я думаю, что в уравнении следует использовать коэффициент contentScale
Ответ №4:
Принятый ответ работает, только если нижнее contentInset
значение неотрицательно. Небольшая эволюция будет учитывать нижнюю часть contentInset
независимо от его знака:
CGFloat bottomInset = scrollView.contentInset.bottom;
CGFloat bottomEdge = scrollView.contentOffset.y scrollView.frame.size.height - bottomInset;
if (bottomEdge == scrollView.contentSize.height) {
// Scroll view is scrolled to bottom
}
Ответ №5:
На самом деле, вместо того, чтобы просто помещать код @bensnider в scrollViewDidScroll, этот код (написанный на Swift 3) был бы более производительным с точки зрения производительности:
func scrollViewDidEndDragging(_ scrollView: UIScrollView,
willDecelerate decelerate: Bool) {
if !decelerate {
checkHasScrolledToBottom()
}
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
checkHasScrolledToBottom()
}
func checkHasScrolledToBottom() {
let bottomEdge = scrollView.contentOffset.y scrollView.frame.size.height
if bottomEdge >= scrollView.contentSize.height {
// we are at the end
}
}
Ответ №6:
Это работает в Swift 3
:
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y == (scrollView.contentSize.height - scrollView.frame.size.height) {
loadMore()
}
}
Ответ №7:
Посмотрите, какие элементы в данный момент отображаются в UIView, используя что-то вроде indexPathsForVisibleRows
, и если в вашей модели больше элементов, чем отображается, поместите стрелку внизу.