iphone - doesn - uiscrollview autolayout
UIScrollView tamaƱo de paginaciĆ³n personalizado (9)
paginar en UIScrollView es una gran característica, lo que necesito aquí es establecer la paginación a una distancia menor, por ejemplo, quiero que mi UIScrollView a la página tenga menos tamaño que el ancho del marco UIScrollView. Gracias
- Cambie su tamaño de scrollView al tamaño de página que desee
- Establezca su
scroll.clipsToBounds = NO
Cree una subclase UIView (por ejemplo, HackClipView) y anule el método hitTest: withEvent:
-(UIView *) hitTest:(CGPoint) point withEvent:(UIEvent *)event { UIView* child = [super hitTest:point withEvent:event]; if (child == self && self.subviews.count > 0) { return self.subviews[0]; } return child; }
Establezca
HackClipView.clipsToBounds = YES
- Coloque su scrollView en este HackClipView (con el tamaño de desplazamiento total que desee)
Vea esta respuesta para más detalles
Actualización: como se indica en la respuesta de lucius, ahora puede implementar el protocolo UIScollViewDelegate
y usar el UIScollViewDelegate
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
. Como targetContentOffset
es un puntero. El uso de este método no le garantizará el mismo resultado con las páginas de vista de desplazamiento, ya que el usuario puede desplazarse por muchas páginas a la vez. Pero establecer la descelerationRate
de descelerationRate
en fast
casi le dará el mismo resultado
Agregar reconocedores de gestos u otras subvistas, etc. es una tontería. Simplemente configure el delegado para la vista de desplazamiento y una imposición de la siguiente:
// This is for a vertical scrolling scroll view.
// Let''s say you want it to snap to every 160 pixels :
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
int y = scrollView.contentOffset.y;
int yOff = y % 160;
if(yOff < 80)
y -= yOff;
else
y += 160 - yOff;
[scrollView setContentOffset:CGPointMake(scrollView.contentOffset.x, y) animated:YES];
}
// This is for a horizontal scrolling scroll view.
// Let''s say you want the same, to snap to every 160 pixels :
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
int x = scrollView.contentOffset.x;
int xOff = x % 160;
if(xOff < 80)
x -= xOff;
else
x += 160 - xOff;
[scrollView setContentOffset:CGPointMake(x, scrollView.contentOffset.y) animated:YES];
}
Debe desactivar la búsqueda y agregar un UIPanGestureRecognizer a su vista de desplazamiento y manejar el paginador usted mismo.
- (void)viewDidLoad {
[super viewDidLoad];
CGRect viewRect = self.view.bounds; // View controller''s view bounds
theScrollView = [[UIScrollView alloc] initWithFrame:viewRect];
theScrollView.scrollsToTop = NO;
theScrollView.pagingEnabled = NO;
theScrollView.delaysContentTouches = NO;
theScrollView.delegate = self;
[self.view addSubview:theScrollView];
UIPanGestureRecognizer * peter = [[[UIPanGestureRecognizer alloc] initWithTarget:self
action:@selector(handlePan:)]
autorelease];
[theScrollView addGestureRecognizer:peter];
}
-(void)handlePan:(UIPanGestureRecognizer*)recognizer{
switch (recognizer.state) {
case UIGestureRecognizerStateBegan:{
// panStart and startPoint are instance vars for the viewContainer
panStart = theScrollView.contentOffset;
startPoint = [recognizer locationInView:theScrollView];
break;
}
case UIGestureRecognizerStateChanged:{
CGPoint newPoint = [recognizer locationInView:theScrollView];
CGFloat delta = startPoint.x - newPoint.x;
if ( abs(delta) > 2)
theScrollView.contentOffset = CGPointMake( theScrollView.contentOffset.x + delta, 0);
CGFloat moveDelta = panStart.x - theScrollView.contentOffset.x;
// current witdh should hold the currently displayed page/view in theScrollView
if ( abs(moveDelta) > (currentWidth * 0.40)){
panStart = theScrollView.contentOffset;
startPoint = newPoint;
//NSLog(@"delta is bigger");
if ( moveDelta < 0 )
[self incrementPageNumber]; // you should implement this method and present the next view
else
[self decrementPageNumber]; // you should implement this method and present the previous view
recognizer.enabled = NO; // disable further event until view change finish
}
break;
}
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
recognizer.enabled = YES;
[self showDocumentPage:currentPage];
break;
default:
break;
}
}
Establezca el contentOffset
en -(void)scrollViewDidScroll:(UIScrollView *)scrollView
método -(void)scrollViewDidScroll:(UIScrollView *)scrollView
.
Consulte también referencias de UIScrollViewDelegate
Esto pareció funcionar mucho mejor para mí:
UIScrollView Paginación personalizada
Aquí están agregando la vista de desplazamiento (manteniendo su aspecto de paginación) como una subvista a una ExtendedTouchView o subclase de UIVIew y sobrescribiendo el método de prueba de impacto
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
if ([self pointInside:point withEvent:event]) {
if ([[self subviews] count] > 0) {
//force return of first child, if exists
return [[self subviews] objectAtIndex:0];
} else {
return self;
}
}
return nil;
}
Esto hizo exactamente lo que yo quería con un código mínimo y dolor de cabeza.
La forma más fácil es agregar este código
scrollView.clipsToBounds = false
scrollView.removeGestureRecognizer(scrollView.panGestureRecognizer)
view.addGestureRecognizer(scrollView.panGestureRecognizer)
Tuve el mismo problema hace poco. Mi enfoque fue agregar un segundo UIScrollView
a la vista de desplazamiento. Entonces puedes cambiar a la página. En esa página parece que si la página es más grande que la pantalla. Espero que funcione también en tu situación. ;-)
Sandro Meier
Tuve el mismo problema, así que hice un UIScrollView personalizado. Está disponible en Github ahora porque cuando busqué no encontré ninguna solución como esta. ¡Disfrutar! https://github.com/MartinMetselaar/MMCPSScrollView
MMCPSScrollView* scrollView = [[MMCPSScrollView alloc] initWithFrame:self.view.bounds];
[scrollView setType:MMCPSScrollVertical];
[scrollView setPageHeight:250];
[scrollView setPageSize:2];
[self.view addSubview:scrollView];
Si tiene más preguntas sobre este componente, solo pregunte.
Hay un método delegado UIScrollView
que puede usar. Establezca su clase como el delegado de la vista de desplazamiento y luego implemente lo siguiente:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
{
CGFloat kMaxIndex = 23;
CGFloat targetX = scrollView.contentOffset.x + velocity.x * 60.0;
CGFloat targetIndex = round(targetX / (kCellWidth + kCellSpacing));
if (targetIndex < 0)
targetIndex = 0;
if (targetIndex > kMaxIndex)
targetIndex = kMaxIndex;
targetContentOffset->x = targetIndex * (kCellWidth + kCellSpacing);
}
El parámetro de velocidad es necesario para asegurarse de que el desplazamiento se siente natural y no termina abruptamente cuando un toque finaliza con el dedo todavía en movimiento. El ancho de celda y el espaciado de celda son el ancho de página y el espaciado entre páginas en su vista. En este caso, estoy usando un UICollectionView
.