seleccion segun opciones lista habilitar ejemplos desplegable deshabilitar objective-c uiwebview ios8

objective c - segun - ios8 iPad uiwebview se bloquea al mostrar una ventana emergente cuando el usuario pulsa la lista desplegable etiqueta de selección de HTML



lista de opciones html (5)

He disminuido la probabilidad de que ocurra una falla de esta manera. Código javascript usado e ios nativo

Cambios en el código web

  1. Registre un detector de eventos ''clic'' en su componente html (desplegable).
  2. En el método de devolución de llamada enviar notificación a código nativo. ej: " window.location=''fromJavaScript://PopoverIssue''; "
  3. shouldStartLoadWithRequest uiwebviews shouldStartLoadWithRequest

Cambios en el código del lado nativo

  1. Implementar el protocolo UIPopoverPresentationControllerDelegate en viewcontroller que tiene uiwebview and over ride popoverPresentationControllerShouldDismissPopover popoverPresentationControllerDidDismissPopover
  2. ponga el código a continuación en el método shouldStartLoadWithRequest de uiwebview para la notificación de clic anterior

    [[UIApplication sharedApplication] beginIgnoringInteractionEvents]; self.popoverPresentationController = self.presentedViewController.popoverPresentationController; self.existedPopoverDelegate = [self.popoverPresentationController delegate]; self.popoverPresentationController.delegate = self; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); dispatch_async(queue, ^{ int64_t delay = 2.0; dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC); dispatch_after(time, dispatch_get_main_queue(), ^{ if([[UIApplication sharedApplication] isIgnoringInteractionEvents]) { [[UIApplication sharedApplication] endIgnoringInteractionEvents]; } }); });

  3. implementar los métodos de protocolo anulados de la siguiente manera

    • (BOOL)popoverPresentationControllerShouldDismissPopover:(UIPopoverPresentationController *)popoverPresentationController { [self.existedPopoverDelegate popoverPresentationControllerShouldDismissPopover:popoverPresentationController]; return YES; }

    • (void)popoverPresentationControllerDidDismissPopover:(UIPopoverPresentationController *)popoverPresentationController { [self.existedPopoverDelegate popoverPresentationControllerDidDismissPopover:popoverPresentationController]; dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0); dispatch_async(queue, ^{ int64_t delay = 2.0; dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC); dispatch_after(time, dispatch_get_main_queue(), ^{ if([[UIApplication sharedApplication] isIgnoringInteractionEvents]) { [[UIApplication sharedApplication] endIgnoringInteractionEvents]; } }); }); }

Espero que ayude a disminuir la ocurrencia del accidente.

En ios8 y iPad si uiwebview muestra una página HTML que contiene una lista desplegable

por ejemplo, esta página http://www.w3schools.com/tags/tryit.asp?filename=tryhtml_select

entonces

  • toque repetidamente la lista desplegable de HTML que contiene listas de autos. El primer artículo es Volvo.
  • toque cada 1/2 segundo o para que uipopover se abra y cierre
  • la aplicación se bloqueará:

La aplicación se cerró debido a la excepción no detectada ''NSGenericException'', motivo: ''UIPopoverPresentationController () debe tener un código fuente no nulo SourceView o barButtonItem establecido antes de que se produzca la presentación.''

¿Hay uiwebview evitar esto en uiwebview en ios8?

No sucede usando wkwebview , pero me gustaría arreglarlo en uiwebview .

Actualización: Esto parece ayudar pero no está seguro de los efectos secundarios. He anulado lo siguiente en el controlador de vista que contiene el uiwebview.

-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion { if (completion) { completion(); } [super dismissViewControllerAnimated:NO completion:nil]; }


La solución mencionada en la pregunta no me ayudó, sin embargo, me indicó la dirección correcta. Después de una investigación, diría que es una condición de carrera entre la presentación y la eliminación de la ventana emergente. Como solución puede posponer la presentación en el delegado de UIWebView:

-(void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_USEC), dispatch_get_main_queue(), ^{ [super presentViewController:viewControllerToPresent animated:flag completion:completion]; }); }


Las soluciones anteriores no me ayudaron.

Hay un error ya registrado en Apple (ver openradar ) para esto.

El problema parece ser que la vista web intenta presentar un controlador de vista en una ventana emergente sin configurar la vista de fuente de la ventana emergente. Aunque definitivamente es un problema de Apple, he usado la siguiente solución para evitar que mi aplicación se bloquee:

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { // Override this method in the view controller that owns the web view - the web view will try to present on this view controller ;) if (viewControllerToPresent.popoverPresentationController && !viewControllerToPresent.popoverPresentationController.sourceView) { return; } [super presentViewController:viewControllerToPresent animated:flag completion:completion]; }


Lo resolví de la siguiente manera después de notar que sourceView está configurado en los casos en que se bloquea:

-(void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { UIPopoverPresentationController* pres = viewControllerToPresent.popoverPresentationController; if(pres.sourceView) { //log the fact you are ignoring the call } else { [super presentViewController:viewControllerToPresent animated:flag completion:completion]; } }


Tuve una excepción diferente en el mismo escenario, y ninguna de las soluciones de aquí me ayudó.

Esta fue mi excepción:

Terminating app due to uncaught exception ''NSRangeException'', reason: ''-[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:]: row (4) beyond bounds (0) for section (0).''

Este es el código que utilicé para solucionarlo:

-(void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion { if ([viewControllerToPresent respondsToSelector:NSSelectorFromString(@"_cachedItems")]) { if([viewControllerToPresent valueForKey:@"_cachedItems"] == nil) { if (completion != nil) { completion(); } return; } } [super presentViewController:viewControllerToPresent animated:flag completion:completion]; }

Es una solución muy desagradable que evita mostrar el menú desplegable en los casos en que está a punto de fallar, y esta solución puede dejar de funcionar en cualquier momento, ya que utiliza propiedades internas. Sin embargo, fue la única solución que funcionó para mí, así que quizás sea útil para alguien.