¿Evitar que UIWebView "rebote" verticalmente?


¿Alguien sabe cómo evitar que un UIWebView rebote verticalmente? Me refiero a cuando un usuario toca la pantalla de su iphone, arrastra su dedo hacia abajo, y la webview muestra un punto en blanco sobre la página web que había cargado?

He mirado las siguientes posibles soluciones, pero ninguna de ellas funcionó para me:

Http://www.iphonedevsdk.com/forum/iphone-sdk-development/996-turn-off-scrolling-bounces-uiwebview.html

Http://forums.macrumors.com/showthread.php?t=619534

¿Cómo puedo evitar que un UIScrollView rebote horizontalmente?

Author: Community, 2009-02-01

22 answers

for (id subview in webView.subviews)
  if ([[subview class] isSubclassOfClass: [UIScrollView class]])
    ((UIScrollView *)subview).bounces = NO;

...parece funcionar bien.

También será aceptado en la App Store.

Actualizar: en iOS 5.x + hay una manera más fácil - UIWebView tiene la propiedad scrollView, por lo que su código puede verse así:

webView.scrollView.bounces = NO;
 405
Author: Mirek Rusin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-05-19 15:57:53

Estaba mirando un proyecto que hace que sea fácil crear aplicaciones web como aplicaciones instalables de pleno derecho en el iPhone llamado QuickConnect , y encontré una solución que funciona, si no desea que su pantalla sea desplazable en absoluto, que en mi caso no lo hice.

En el proyecto/blog mencionado anteriormente, mencionan una función javascript que puede agregar para desactivar el rebote, que esencialmente se reduce a esto:

    document.ontouchmove = function(event){
        event.preventDefault();
    }

Si quieres ver más sobre cómo impleméntelo, simplemente descargue QuickConnect y compruébelo.... Pero básicamente todo lo que hace es llamar a ese javascript en la carga de la página... Traté de ponerlo en la cabeza de mi documento, y parece que funciona bien.

 45
Author: Brad Parks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-12 11:39:51

Bueno, todo lo que hice para lograr esto es :

UIView *firstView = [webView.subviews firstObject];

if ([firstView isKindOfClass:[UIScrollView class]]) {

    UIScrollView *scroll = (UIScrollView*)firstView;
   [scroll setScrollEnabled:NO];  //to stop scrolling completely
   [scroll setBounces:NO]; //to stop bouncing 

}

Funciona bien para mí... Además, la respuesta marcada para esta pregunta es una que Apple rechazará si la usa en tu aplicación para iphone.

 18
Author: Zigglzworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-25 07:15:20

En el SDK de iOS 5 puede acceder a la vista de desplazamiento asociada con una vista web directamente en lugar de iterar a través de sus subviews.

Así que para desactivar 'rebotar' en la vista de desplazamiento puedes usar:

myWebView.scrollView.bounces = NO;

Ver la Referencia de la clase UIWebView .

(Sin embargo, si necesita admitir versiones del SDK anteriores a la 5.0, debe seguir El consejo de Mirek Rusin.)

 17
Author: jstr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:02:50

Advertencia. Usé setAllowsRubberBanding: en mi aplicación, y Apple lo rechazó, indicando que las funciones API no públicas no están permitidas (cite: 3.3.1)

 9
Author: Raf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-11-16 17:29:31

Swift 3

webView.scrollView.bounces = false
 7
Author: Ego Slayer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-16 06:58:36

En Swift para desactivar rebotes

webViewObj.scrollView.bounces = false
 4
Author: Jugal K Balara,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-01 10:13:13

El método de Brad funcionó para mí. Si lo usas es posible que quieras hacerlo un poco más seguro.

id scrollView = [yourWebView.subviews objectAtIndex:0];
if( [scrollView respondsToSelector:@selector(setAllowsRubberBanding:)] )
{
    [scrollView performSelector:@selector(setAllowsRubberBanding:) withObject:NO];
}

Si Apple cambia algo, el rebote volverá, pero al menos tu aplicación no se bloqueará.

 3
Author: Gavin Maclean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-07-18 15:21:32

En iOS5 solo si planea permitir que los usuarios amplíen el contenido de webview (por ejemplo: doble toque), la configuración de rebote no es suficiente. Debe establecer también alwaysBounceHorizontal y alwaysBounceVertical properties en NO, de lo contrario, cuando se alejan (otro toque doble...) por defecto rebotará de nuevo.

 3
Author: il Malvagio Dottor Prosciutto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-12 08:05:09

Recorrí la colección de subviews de UIWebView y establecí sus fondos en [UIColor blackColor], el mismo color que el fondo de la página web. La vista aún rebotará, pero no mostrará ese feo fondo gris oscuro.

 2
Author: pedro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-03-02 09:51:13

Me parece que el UIWebView tiene un UIScrollView. Puede usar API documentadas para esto, pero el rebote está configurado para ambas direcciones, no individualmente. Esto está en los documentos de la API. UIScrollView tiene una propiedad bounce, así que algo como esto funciona (no sé si hay más de un scrollview):

NSArray *subviews = myWebView.subviews;
NSObject *obj = nil;
int i = 0;
for (; i < subviews.count ; i++)
{
    obj = [subviews objectAtIndex:i];

    if([[obj class] isSubclassOfClass:[UIScrollView class]] == YES)
    {
        ((UIScrollView*)obj).bounces = NO;
    }
}
 2
Author: spymaster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-03 08:05:36

Me molestó saber que UIWebView no es una vista de desplazamiento, así que hice una subclase personalizada para llegar a la vista de desplazamiento de la vista web. Esta suclass contiene una vista de desplazamiento para que pueda personalizar el comportamiento de su vista web. Los punchlines de esta clase son:

@class CustomWebView : UIWebview
...

- (id) initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
// WebViews are subclass of NSObject and not UIScrollView and therefore don't allow customization.
// However, a UIWebView is a UIScrollViewDelegate, so it must CONTAIN a ScrollView somewhere.
// To use a web view like a scroll view, let's traverse the view hierarchy to find the scroll view inside the web view.
for (UIView* v in self.subviews){
    if ([v isKindOfClass:[UIScrollView class]]){
        _scrollView = (UIScrollView*)v; 
        break;
    }
}
return self;

}

Luego, cuando cree una vista web personalizada, puede deshabilitar el rebote con:

customWebView.scrollView.bounces = NO; //(or customWebView.scrollView.alwaysBounceVertically = NO)

Esta es una gran manera de propósito general para hacer una vista web con un comportamiento de desplazamiento personalizable. Hay solo unos pocos cosas a tener en cuenta:

  • al igual que con cualquier vista, también necesitará anular -(id)initWithCoder: si lo usa en Interface Builder
  • cuando se crea inicialmente una vista web, su tamaño de contenido es siempre el mismo que el tamaño del marco de la vista. Después de desplazarse por la web, el tamaño del contenido representa el tamaño del contenido web real dentro de la vista. Para evitar esto, hice algo hacky-calling-setContentOffset: CGPointMake (0,1)animado: SÍ para forzar un imperceptible cambio que establecerá el tamaño de contenido adecuado de la vista web.
 2
Author: Rolf Hendriks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-08 20:55:54

Me encontré con esto en busca de una respuesta y finalmente solo tuve suerte en una respuesta de mi propia por jugar. Lo hice

[[webview scrollView] setBounces:NO];

Y funcionó.

 2
Author: Luke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-20 13:57:30

Esto funcionó para mí, y muy bien también (estoy usando phonegap con WebView)

[[webView.webView scrollView] setScrollEnabled:NO];

O

[[webView scrollView] setScrollEnabled:NO];
 2
Author: Jason G,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-21 19:02:14

Probé un enfoque ligeramente diferente para evitar que los objetos UIWebView se desplacen y reboten: agregar un reconocedor de gestos para anular otros gestos.

Parece que, UIWebView o su subview scroller usa su propio reconocedor de gestos de pan para detectar el desplazamiento del usuario. Pero de acuerdo con la documentación de Apple, hay una forma legítima de anular un reconocedor de gestos con otro. El protocolo UIGestureRecognizerDelegate tiene un método gestureRecognizer:shouldRecognizeSimultaneouslyWithgesturerecognizer:, que permite controlar el comportamiento de cualquier colisión gesto de reconocedores.

Entonces, lo que hice fue

En el método viewDidLoad del controlador de vista:

// Install a pan gesture recognizer                                                                                        // We ignore all the touches except the first and try to prevent other pan gestures                                                     
// by registering this object as the recognizer's delegate                                                                                        
UIPanGestureRecognizer *recognizer;                                                                                                               
recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];                                                   
recognizer.delegate = self;                                                                                                                       
recognizer.maximumNumberOfTouches = 1;                                                                                                            
[self.view addGestureRecognizer:recognizer];                                                                                                          
self.panGestureFixer = recognizer;                                                                                                                  
[recognizer release]; 

Luego, el método de anulación de gestos:

// Control gestures precedence                                                                                                                            
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer                                                                                        
        shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer                                                  
{                                                                                                                                                         
        // Prevent all panning gestures (which do nothing but scroll webViews, something we want to disable in                                          
        // the most painless way)                                                                                                                         
        if ([otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])                                                                        
        {
            // Just disable every other pan gesture recognizer right away                                                                             
            otherGestureRecognizer.enabled = FALSE;
        }                                                                                                                                                  
        return NO;                                                                                                                                        
}              

Por supuesto, este método de delegado me puede ser más complejo en una aplicación real - podemos desactivar otros recognizers selectivamente, analizando Otherergesturerecognizer.ver y hacer decisión basada en qué punto de vista es.

Y, finalmente, en aras de la integridad, el método que registramos como un pan handler:

- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer 
{ 
    // do nothing as of yet
}

Puede estar vacío si todo lo que queremos es cancelar el desplazamiento y el rebote de las vistas web, o puede contener nuestro propio código para implementar el tipo de movimientos de panorámica y animaciones que realmente queremos...

Hasta ahora solo estoy experimentando con todas estas cosas, y parece estar funcionando más o menos como quiero. Todavía no he intentado enviar ninguna aplicación a iStore, aunque. Pero creo que no he usado nada indocumentado hasta ahora... Si alguien lo encuentra de otra manera, por favor infórmeme.

 1
Author: PP-RD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-10 09:00:46

Aquí hay dos nuevas soluciones potenciales. Aparentemente, puede usar jqtouch o pastrykit para deshabilitar el desplazamiento. Sin embargo, no tengo estos para trabajar. Podrías ser más competente.

Desactivar el desplazamiento vertical

Cavando en pastrykit

 1
Author: cannyboy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-18 10:06:07

Posicionamiento fijo en mobile safari

Este enlace me ayudó mucho.....Es fácil.. Hay una demo..

 1
Author: S.P.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-18 10:21:19

(ejemplo de Xcode 5 iOS 7 SDK) Aquí hay un ejemplo de aplicación Universal que usa la función scrollview setBounces. Es un proyecto / ejemplo de código abierto ubicado aquí: Enlace a SimpleWebView (Proyecto Zip y Ejemplo de Código Fuente)

 1
Author: Matthew Ferguson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-21 04:20:28

Una de las subviews de UIWebView debe ser UIScrollView. Establezca su propiedad scrollEnabled en NO y la vista web tendrá el desplazamiento desactivado por completo.

Nota: esto está técnicamente utilizando una API privada y, por lo tanto, su aplicación podría ser rechazada o bloqueada en futuras versiones del sistema operativo. Use @try y respondsToSelector

 0
Author: rpetrich,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-02 13:16:11

Busque en la propiedad bounces de UIScrollView. Quoth el Apple docs:

Si el valor de la propiedad es YES (el valor predeterminado), la vista de desplazamiento rebota cuando encuentra un límite del contenido. El rebote visualmente indica que el desplazamiento ha alcanzado un borde del contenido. Si el valor es NO, el desplazamiento se detiene inmediatamente en el límite de contenido sin rebotar.

Asegúrate de usar el UIScrollView correcto. No estoy seguro de cómo se ve la jerarquía para un UIWebView, pero la vista de desplazamiento podría ser un padre, no un hijo, de la UIWebView.

 0
Author: Alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-02-06 16:47:16

Para deshabilitar el desplazamiento UIWebView puede usar la siguiente línea de código:

[ObjWebview setUserInteractionEnabled:FALSE];

En este ejemplo, ObjWebview es del tipo UIWebView.

 0
Author: Sandip Patel - SM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-10-05 22:20:29

WebView.ScrollView.scrollEnabled = NO; WebView.ScrollView.rebotes = NO;

 0
Author: Kumaresan P,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-09-10 10:00:43