Deshabilitar el desplazamiento vertical en UIScrollView

Respuestas:

121

Intente establecer la altura de contentSize a la altura de scrollView. Entonces el desplazamiento vertical debería estar deshabilitado porque no habría nada para desplazarse verticalmente.

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width,scrollView.frame.size.height);
pt2ph8
fuente
Me ahorraste mucho tiempo depurando este extraño problema. ¡Gracias!
jpm
2
@fabb ¿cómo se sabe cuando se cambia el marco?
Sam
137

desde iOS7:

primero: el ancho del tamaño del contenido debe ser igual al ancho de su vista de desplazamiento

segundo: en su initWithNibName:

self.automaticallyAdjustsScrollViewInsets = NO;

Eso es.

Mirko Brunner
fuente
Maravillosa solucion. Trabajado como un encanto. ¿Afectará el tamaño del resto de las vistas en mi ViewController? (Botones, etiquetas ...) Quiero decir, "self" es un UIViewController en mi caso
voghDev
@voghDev no, no tiene ningún efecto en las subvistas de su vista de desplazamiento.
Mirko Brunner
Amazing agregó esto al método viewdidload en mis controladores de vista que tenían problemas.
StackRunner
si está usando navigationController y su vista de desplazamiento está detrás del título de la barra de navegación como el mío, use el método viewDidLoad. Resuelve.
EFE
1
Puede lograr lo mismo en la configuración del guión gráfico directamente sin ninguna línea de código. Simplemente seleccione el controlador de vista de desplazamiento y desmarque "Ajustar inserciones de vista de desplazamiento" en el inspector de atributos.
Morpheus78
49

sí, la respuesta de pt2ph8 es correcta,

pero si por alguna extraña razón su contentSize debería ser mayor que el UIScrollView, puede deshabilitar el desplazamiento vertical implementando el método del protocolo UIScrollView

 -(void)scrollViewDidScroll:(UIScrollView *)aScrollView;

solo agregue esto en su UIViewController

float oldY; // here or better in .h interface

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
    [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x, oldY)];
    // or if you are sure you wanna it always on top:
    // [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x, 0)];
}

es solo el método llamado cuando el usuario desplaza su UIScrollView, y al hacerlo, fuerza el contenido a tener siempre el mismo .y

meronix
fuente
6
¡Dios! NO declare la variable oldY en el archivo .m como float oldY;consulte el código anterior. Ese es un símbolo de variable de estilo C para cada aplicación, la variable DEBE declararse como un miembro de instancia de la clase de controlador.
Itachi
21

Incluya el siguiente método

-(void)viewDidLayoutSubviews{
    self.automaticallyAdjustsScrollViewInsets = NO;
}

y establezca el ancho del tamaño del contenido de la vista de desplazamiento igual al ancho de la vista de desplazamiento.

Febin P
fuente
1
Esto también se puede hacer en Storyboard seleccionando el Controlador de vista y desmarcando la propiedad allí
justColbs
1
No me gusta esto porque lo establece para todas las vistas de desplazamiento ... Ojalá pudiera ser específico para una vista de desplazamiento en el diagrama sin crear una nueva clase de ScrollView
etc.- visc
20

Debe pasar 0 en el tamaño del contenido para deshabilitar en la dirección que desee.

Para deshabilitar el desplazamiento vertical

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width,0);

Para deshabilitar el desplazamiento horizontal

scrollView.contentSize = CGSizeMake(0,scrollView.contentSize.height);
Mani
fuente
1
Esto establecerá el contentSize de la vista en 0 en el eje que establezca. ContentSize se refiere al tamaño del contenido, por lo que queremos pasar la altura de la pantalla para deshabilitar el desplazamiento vertical más allá de ese marco. la solución marcada como correcta, es correcta.
sistema
Esto funcionó bien para mí. establecer la altura como altura de contentSize todavía me hizo desplazarme verticalmente.
KoreanXcodeWorker
1
Esto no funcionó para mí. También probé self.automaticallyAdjustsScrollViewInsets
StackRunner
¡Eso es todo! Establecer la altura de la Vista de desplazamiento no funcionó para mí, pero esto funcionó
Echizzle
18

Actualicé el tamaño del contenido para deshabilitar el desplazamiento vertical y la capacidad de desplazamiento aún permanecía. Luego me di cuenta de que también necesitaba deshabilitar el rebote vertical, para deshabilitar completamente el desplazamiento.

Quizás también haya personas con este problema.

bolonn
fuente
Me salvaste. El tamaño y el marco de mi contenido eran los mismos y no pude por mi vida averiguar qué estaba mal. ¡¡Gracias un montón!!
yuf
2
¡Tu respuesta es por qué me encanta stackoverflow! :-) Santo humo ... ¡esto me volvió loco! Tienes razón. Es el efecto de rebote. Quiero el efecto de rebote, pero no cuando no hay necesidad de desplazarse, por lo que buscaré deshabilitar / volver a habilitar ese efecto ahora en el código, dependiendo de si es necesario desplazarse.
Erik van der Neut
2
Bien, es muy fácil habilitar / deshabilitar los rebotes en un UIScrollView en tiempo de ejecución. En mi caso, solo me importa la altura del contenido de desplazamiento y esto funcionó: self.scrollView.bounces = (BOOL) (self.scrollView.contentSize.height> self.scrollView.frame.size.height);
Erik van der Neut
12
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
    [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x,0)];

}

debes haber confirmado UIScrollViewDelegate

aScrollView.delegate = self;

fuente
4

Simplemente configure la y para que esté siempre arriba. Necesita cumplir con UIScrollViewDelegate

func scrollViewDidScroll(scrollView: UIScrollView) {
        scrollView.contentOffset.y = 0.0
}

Esto mantendrá el efecto de desaceleración / aceleración del desplazamiento.

manuelsantos
fuente
4

En iOS 11, recuerde agregar lo siguiente, si está interesado en crear una vista de desplazamiento que se adhiera a los límites de la pantalla en lugar de un área segura:

if (@available(iOS 11.0, *)) {
    [self.scrollView setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}
Miguel
fuente
1
después de todo. gracias mil veces señor! me salvaste el día
ha100
0

Desde iOS11 se puede utilizar la siguiente propiedad

let frameLayoutGuide: UILayoutGuide

Si establece restricciones para frameLayoutGuide.topAnchor y frameLayoutGuide.bottomAnchor a los mismos anclajes de alguna subvista de su scrollView , el desplazamiento vertical se desactivará y la altura de scrollView será igual a la altura de su subvista.

malex
fuente
0

La solución más obvia es prohibir los cambios de coordenadas y en su subclase.

override var contentOffset: CGPoint {
  get {
    return super.contentOffset
  }
  set {
    super.contentOffset = CGPoint(x: newValue.x, y: 0)
  }
}

Ésta es la única solución adecuada en situaciones en las que:

  1. No está permitido o simplemente no quiere usar delegado.
  2. La altura de su contenido es mayor que la altura del contenedor
iWheelBuy
fuente
0

Muchas respuestas incluyen establecer el contentOffseten 0. Tuve un caso en el que quería que la vista dentro de scrollView estuviera centrada. Esto hizo el trabajo por mí:

public func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = -scrollView.contentInset.top
}
regina_fallangi
fuente