objective c - tutorial - UIScrollView deshabilita el rebote vertical solo en la parte inferior
swift(lenguaje de programaciĆ³n) (6)
He estado buscando una manera de deshabilitar el rebote vertical para un UIScrollView pero solo en la parte inferior. Todavía necesito tener el rebote en la parte superior.
No se pudo encontrar nada. es posible?
¡Gracias por adelantado!
Agregué fabsf()
a la solución 0x7fffffff ♦ para atender también el desplazamiento negativo (hacia abajo):
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (fabsf(scrollView.contentOffset.y) >= scrollView.contentSize.height - scrollView.frame.size.height) {
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, scrollView.contentSize.height - scrollView.frame.size.height)];
}
}
Basándome en la respuesta de 0x7fffffff, he creado una clase:
VerticalBounceControl.h
#import <UIKit/UIKit.h>
@interface VerticalBounceControl : NSObject
@property (nonatomic, assign) BOOL bounce;
- (id) initWithScrollView:(UIScrollView*)scrollView bounceAtTop:(BOOL)bounceAtTop bounceAtBottom:(BOOL)bounceAtBottom;
@end
VerticalBounceControl.m
#import "VerticalBounceControl.h"
@interface VerticalBounceControl ()
@property (nonatomic, retain) UIScrollView* scrollView;
@property (nonatomic, assign) BOOL bounceAtTop;
@property (nonatomic, assign) BOOL bounceAtBottom;
@end
@implementation VerticalBounceControl
- (id) initWithScrollView:(UIScrollView*)scrollView bounceAtTop:(BOOL)bounceAtTop bounceAtBottom:(BOOL)bounceAtBottom {
self = [super init];
if(self) {
self.bounce = YES;
self.scrollView = scrollView;
self.bounceAtTop = bounceAtTop;
self.bounceAtBottom = bounceAtBottom;
[self.scrollView addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:NULL];
}
return self;
}
- (void) dealloc {
[self.scrollView removeObserver:self forKeyPath:@"contentOffset"];
self.scrollView = nil;
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"contentOffset"]) {
if (self.bounce && ((self.scrollView.contentOffset.y<=0 && self.bounceAtTop) || (self.scrollView.contentOffset.y>=self.scrollView.contentSize.height-1 && self.bounceAtBottom))) {
self.scrollView.bounces = YES;
} else {
self.scrollView.bounces = NO;
}
}
}
@end
que se puede usar sin que la persona que llama sea un delegado de UIScrollView
como este:
VerticalBounceControl* bounceControl = [[VerticalBounceControl alloc] initWithScrollView:anyScrollView bounceAtTop:YES bounceAtBottom:NO];
De esta manera, puede tener este comportamiento de rebote para los UIScrollView
que no desea modificar su delegado (como el de UIWebView
).
Nuevamente, ¡gracias a @ 0x7fffffff por la solución!
He estado buscando una solución para deshabilitar el rebote inferior solo para una vista de desplazamiento con un ancho de tamaño de contenido más amplio que el dispositivo desde que uso la paginación. Nada de eso me funciona, pero encontré la manera de hacerlo. Pensé que debería compartir esto ya que perdí dos días solo para hacer esto. Estoy usando Swift 4, pero esto se aplica al objetivo c si sabes cómo convertir esto, lo que debería ser fácil si tienes experiencia con ambos.
Esto funciona en una vista de desplazamiento con el marco de la pantalla del dispositivo como marco.
Agregar variable para tener en cuenta para la página actual de scrollview.
var currentPage : Int!
Establecer el valor inicial
currentPage = 0
Actualizar
currentPage
después de desplazarse
public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { let width = scrollView.frame.size.width let page = (scrollView.contentOffset.x + (0.5 * width)) / width currentPage = Int(page) }
Filtre la parte inferior del desplazamiento y actualice el contenido.
public func scrollViewDidScroll(_ scrollView: UIScrollView) { if CGFloat(currentPage) * screenWidth < scrollView.contentOffset.x || CGFloat(currentPage) * screenWidth < scrollView.contentOffset.y || (((CGFloat(currentPage) * screenWidth - scrollView.contentOffset.x) >= 0) && scrollView.contentOffset.y > 0){ scrollView.contentOffset.y = 0 } }
CGFloat(currentPage) * screenWidth < scrollView.contentOffset.x || CGFloat(currentPage) * screenWidth < scrollView.contentOffset.y
CGFloat(currentPage) * screenWidth < scrollView.contentOffset.x || CGFloat(currentPage) * screenWidth < scrollView.contentOffset.y
filtrará el desplazamiento hacia la izquierda y hacia la derecha
(((CGFloat(currentPage) * screenWidth - scrollView.contentOffset.x) >= 0) && scrollView.contentOffset.y > 0)
filtrará la parte inferior del desplazamiento medio
scrollView.contentOffset.y = 0
evitará que se desplace
Para deshabilitar el rebote vertical en la parte superior en Swift:
func scrollViewDidScroll(scrollView: UIScrollView) {
if scrollView.contentOffset.y < 0 {
scrollView.contentOffset.y = 0
}
}
Utilice el método scrollViewDidScroll
UIScrollViewDelegate para verificar el desplazamiento de contenido de la vista de desplazamiento y verifique si el usuario está intentando desplazarse más allá de los límites inferiores de la vista de desplazamiento. Luego, use esto para configurar el desplazamiento de nuevo al final de la vista de desplazamiento. Sucede tan rápido que ni siquiera se puede decir que la vista de desplazamiento rebotó o se extendió más allá de sus límites.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.contentOffset.y >= scrollView.contentSize.height - scrollView.frame.size.height) {
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, scrollView.contentSize.height - scrollView.frame.size.height)];
}
}
Swift 3:
Esto funciona para deshabilitar el rebote vertical solo en la parte inferior:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollView.contentOffset.y > scrollView.contentSize.height - scrollView.bounds.height {
scrollView.contentOffset.y = scrollView.contentSize.height - scrollView.bounds.height
}
}