iphone - app - webview swift 4 example
mostrando el menú personalizado en la selección en UIWebView en iphone (2)
En veloz
class ViewController: UIViewController {
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
// add two custom menu items to the context menu of UIWebView (assuming in contenteditable mode)
let menuItem1 = UIMenuItem(title: "Foo", action: #selector(ViewController.foo))
let menuItem2 = UIMenuItem(title: "Bar", action: #selector(ViewController.bar))
UIMenuController.sharedMenuController().menuItems = [menuItem1, menuItem2]
}
override func viewDidDisappear(animated: Bool) {
super.viewDidAppear(animated)
UIMenuController.sharedMenuController().menuItems = nil
}
override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
if webView?.superview != nil {
if action == #selector(ViewController.foo) || action == #selector(ViewController.bar) {
return true
}
}
return super.canPerformAction(action, withSender: sender)
}
func foo() {
print("foo")
}
func bar() {
print("bar")
}
}
Nota: #selector está disponible en Swift 2.2.
Quiero mostrar 2 opciones como "hi" y "bye" cuando el usuario completa la selección en UIWebView.
He añadido observador a mi controlador de vista de la siguiente manera. Pero no sé más implementación.
[[UIMenuController sharedMenuController] addObserver:self
forKeyPath:UIMenuControllerWillShowMenuNotification
options:nil
context:nil
];
Sagar,
Tu pregunta tiene un par de meses, pero finalmente me di cuenta de esto, así que pensé en contestarla en caso de que ayude a alguien más.
Agregué el siguiente código al método viewDidAppear: del controlador de vista que contiene la vista web.
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
UIMenuItem *customMenuItem1 = [[[UIMenuItem alloc] initWithTitle:@"Custom 1" action:@selector(customAction1:)] autorelease];
UIMenuItem *customMenuItem2 = [[[UIMenuItem alloc] initWithTitle:@"Custom 2" action:@selector(customAction2:)] autorelease];
[[UIMenuController sharedMenuController] setMenuItems:[NSArray arrayWithObjects:customMenuItem1, customMenuItem2, nil]];
}
En mi viewDidDisappear :, sigo adelante y elimino esos elementos:
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[[UIMenuController sharedMenuController] setMenuItems:nil];
}
Luego, implementé el método canPerformAction: withSender: en el controlador de vista. Ayuda a entender el concepto de respondedores y cadenas de respondedores para entender lo que está sucediendo aquí. Básicamente, su controlador uiview es parte de la cadena de respondedores, por lo que se le pregunta si puede manejar alguna acción (como las acciones personalizadas que agregó anteriormente) que los objetos que están más arriba en la cadena de respondedores (como UIWebView) no saben cómo manejar ( consulte la documentación de UIResponder y la Guía de manejo de eventos para iOS para obtener información detallada).
Ahora, cuando se llama a canPerformAction: withSender: para la vista web, el parámetro sender se establece en nil. Por lo tanto, trato de ser un poco inteligente acerca de cómo escribo esta función. Básicamente, me aseguro de que el remitente sea nulo, muestre la vista web al usuario y cualquier otro control en la página no sea el primero en responder. Si ese es el caso, entonces verifico si esta es una de las acciones que definí anteriormente y vuelvo a responder SÍ si lo es. En todos los demás casos, devuelvo el valor predeterminado de UIViewController llamando al mismo método en super.
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
if (webView.superview != nil && ![urlTextField isFirstResponder]) {
if (action == @selector(customAction1:) || action == @selector(customAction2:)) {
return YES;
}
}
return [super canPerformAction:action withSender:sender];
}
Por supuesto, ahora el siguiente paso es descubrir cómo hacer algo con la selección (probablemente ejecutando algo de JavaScript en la vista web).