Parar UIWebView de “saltando” verticalmente?

Alguém sabe como parar um UIWebView de saltar verticalmente? Quero dizer, quando um usuário toca na canvas do seu iPhone, arrasta o dedo para baixo, e a webview mostra um ponto em branco acima da página da web que eu carreguei?

Eu olhei para as seguintes possíveis soluções, mas nenhuma delas funcionou para mim:

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

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

Como faço para parar um UIScrollView de saltar horizontalmente?

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

… parece funcionar bem.

Também será aceito na App Store.

Atualização : no iOS 5.x + há uma maneira mais fácil – o UIWebView possui a propriedade scrollView , assim seu código pode ficar assim:

 webView.scrollView.bounces = NO; 

Eu estava olhando para um projeto que torna fácil criar aplicativos web como aplicativos instaláveis ​​completos no iPhone chamado QuickConnect , e encontrei uma solução que funciona, se você não quiser que sua canvas seja rolável, o que no meu caso Eu não fiz.

No projeto / blog mencionado acima, eles mencionam uma function javascript que você pode adicionar para desativar o salto, que essencialmente se resume a isto:

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

Se você quiser ver mais sobre como eles o implementam, simplesmente baixe o QuickConnect e confira …. Mas basicamente tudo o que ele faz é chamar isso de javascript no carregamento da página … Eu tentei apenas colocá-lo na cabeça do meu documento, e parece funcionar bem.

Bem, tudo que fiz para conseguir isso é:

 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 bem para mim … Além disso, a resposta marcada para esta pergunta é aquela que a Apple irá rejeitar se você usá-lo em seu aplicativo para iPhone.

No iOS 5 SDK, você pode acessar a visualização de rolagem associada a uma visualização da Web diretamente, em vez de percorrer suas subvisualizações.

Então, para desabilitar o ‘salto’ na canvas de rolagem, você pode usar:

 myWebView.scrollView.bounces = NO; 

Veja a Referência da Classe UIWebView .

(No entanto, se você precisar dar suporte a versões do SDK antes de 5.0, deverá seguir o conselho de Mirek Rusin .)

Atenção. Eu usei setAllowsRubberBanding: no meu aplicativo, e a Apple o rejeitou, afirmando que as funções não públicas da API não são permitidas (cite: 3.3.1)

Swift 3

 webView.scrollView.bounces = false 

No Swift para desativar rejeições

 webViewObj.scrollView.bounces = false 

O método de Brad funcionou para mim. Se você usá-lo, você pode querer torná-lo um pouco mais seguro.

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

Se a apple mudar alguma coisa, a rejeição voltará, mas pelo menos seu aplicativo não irá falhar.

No iOS5 apenas se você planeja permitir que os usuários ampliem o conteúdo da webview (ei: toque duplo) a configuração de rejeição não é suficiente. Você precisa definir também as propriedades alwaysBounceHorizontal e alwaysBounceVertical como NO, senão quando elas diminuem o zoom (outro toque duplo …) para o padrão, ele retorna novamente.

Eu percorri a coleção de subvisualizações do UIWebView e defini seus planos de fundo para [UIColor blackColor], a mesma cor do plano de fundo da página da Web. A visão ainda vai saltar, mas não mostrará aquele fundo cinza escuro e feio.

Parece-me que o UIWebView tem um UIScrollView. Você pode usar APIs documentadas para isso, mas a rejeição é definida para ambas as direções, não individualmente. Isso está nos documentos da API. O UIScrollView tem uma propriedade de rejeição, então algo assim funciona (não sei se há mais de um 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; } } 

Fiquei irritado ao descobrir que o UIWebView não é uma visualização de rolagem, então criei uma subclass personalizada para obter a exibição de rolagem da visualização da Web. Essa suclass contém uma visualização de rolagem para que você possa personalizar o comportamento da sua visualização da web. As punchlines desta class são:

 @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; 

}

Em seguida, quando você criar uma visualização da Web personalizada, poderá desativar a rejeição com:

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

Essa é uma ótima maneira geral de criar uma visualização da Web com um comportamento de rolagem personalizável. Há apenas algumas coisas a observar:

  • como com qualquer visão, você também precisará sobrescrever – (id) initWithCoder: se você usá-lo no Interface Builder
  • Quando você cria inicialmente uma visualização da Web, seu tamanho de conteúdo é sempre igual ao tamanho do quadro da exibição. Depois de percorrer a web, o tamanho do conteúdo representa o tamanho do conteúdo real da web dentro da exibição. Para contornar isso, fiz algo hacky – chamando -setContentOffset: CGPointMake (0,1) animado: YES para forçar uma alteração imperceptível que definirá o tamanho apropriado do conteúdo da visualização da web.

Veio em toda esta busca por uma resposta e acabei por sorte em uma resposta própria por mexer. eu fiz

 [[webview scrollView] setBounces:NO]; 

e funcionou.

Isso funcionou para mim e muito bem (estou usando o phonegap com o webView)

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

ou

 [[webView scrollView] setScrollEnabled:NO]; 

Eu tentei uma abordagem ligeiramente diferente para evitar que os objects UIWebView rolassem e saltassem: adicionando um reconhecedor de gestos para replace outros gestos.

Ao que parece, o UIWebView ou sua subview de scroller usa seu próprio reconhecedor de gesto de pan para detectar a rolagem do usuário. Mas, de acordo com a documentação da Apple, existe uma maneira legítima de replace um reconhecedor de gestos por outro. O protocolo UIGestureRecognizerDelegate possui um método gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer: – que permite controlar o comportamento de qualquer reconhecedor de gestos em colisão.

Então, o que eu fiz foi

no método viewDidLoad do view controller:

 // 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]; 

então, o método de substituição 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; } 

É claro que esse método delegado pode me tornar mais complexo em um aplicativo real – podemos desabilitar outros reconhecedores seletivamente, analisando otherGestureRecognizer.view e tomando decisões com base em qual visão ele é.

E, finalmente, por uma questão de completude, o método que registramos como um manipulador de pan:

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

pode estar vazio se tudo o que queremos é cancelar a rolagem e a repercussão das visualizações da Web, ou pode conter nosso próprio código para implementar o tipo de movimentos e animações panorâmicas que realmente desejamos …

Até agora eu estou apenas experimentando todas essas coisas, e parece estar funcionando mais ou menos como eu quero. Ainda não tentei enviar aplicativos para o iStore. Mas eu acredito que não usei nada não documentado até agora … Se alguém encontrar o contrário, por favor me informe.

Aqui estão duas novas soluções possíveis. Aparentemente, você pode usar jqtouch ou pastrykit para desativar a rolagem. No entanto, eu não tenho esses para trabalhar. Você pode ser mais competente.

desligando a rolagem vertical

cavando em kit de pascanvasria

posicionamento fixo no safari móvel

Este link me ajudou muito ….. É fácil .. Há uma demonstração ..

(Exemplo de Xcode 5 iOS 7 SDK) Aqui está um exemplo de Universal App usando a function scrollview setBounces. É um projeto / exemplo de código aberto localizado aqui: Link para SimpleWebView (Exemplo de código-fonte e código- fonte do projeto )

Uma das subvisualizações do UIWebView deve ser um UIScrollView . Defina sua propriedade scrollEnabled como NO e a visualização da Web terá a rolagem totalmente desativada.

Nota: isso é tecnicamente usando uma API privada e, portanto, seu aplicativo pode ser rejeitado ou travar em versões futuras do sistema operacional. Use @try e respondsToSelector

Olhe para a propriedade bounces do UIScrollView . Quoth a Apple docs:

Se o valor da propriedade for YES (o padrão), a exibição de rolagem será refletida quando encontrar um limite do conteúdo. Saltar visualmente indica que a rolagem atingiu uma borda do conteúdo. Se o valor for NO , a rolagem pára imediatamente no limite de conteúdo sem saltar.

Verifique se você está usando o UIScrollView correto. Não tenho certeza de como é a hierarquia de um UIWebView , mas a exibição de rolagem pode ser um pai, não um filho, do UIWebView .

Para desabilitar a rolagem do UIWebView você pode usar a seguinte linha de código:

 [ObjWebview setUserInteractionEnabled:FALSE]; 

Neste exemplo, ObjWebview é do tipo UIWebView .

webView.scrollView.scrollEnabled = NÃO; webView.scrollView.bounces = NÃO;