iOS: descarta el teclado cuando tocas fuera de UITextField


461

Me pregunto cómo hacer que el teclado desaparezca cuando el usuario toca fuera de a UITextField.


8
Dmitry tenía la respuesta correcta. Este no es un problema de gestos, es un problema de renunciar al primer respondedor. La respuesta de Dmirty también es la solución recomendada por Mark, Nutting y LeMarche en Beginning iOS 4 Development , Capítulo 4, página 83.
jww

Respuestas:


760

Tendrá que agregar un UITapGestureRecognisery asignarlo a la vista, y luego llamar a resignar primer respondedor UITextFielden su selector.

El código:

En vistaDidLoad

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)];

[self.view addGestureRecognizer:tap];

En despedir Teclado:

-(void)dismissKeyboard 
{
    [aTextField resignFirstResponder];
}

(¿Dónde aTextFieldestá el campo de texto responsable del teclado?)

La versión Swift 3 se ve así

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.dismissKeyboard (_:)))
self.view.addGestureRecognizer(tapGesture)

Para despedir Keyboard

@objc func dismissKeyboard (_ sender: UITapGestureRecognizer) {
    aTextField.resignFirstResponder()
}

66
Esto funciona, pero lo que hace es que también deshabilita o hace que los botones de la barra de navegación no se puedan hacer clic. Entonces, ¿hay una solución para esto?
Parth Bhatt

137
Creo que mejor de [aTextField resignFirstResponder]lo que sería [self.view endEditing:YES];, no necesita una referencia al campo de texto y funcionará para múltiples campos de texto
Julian Król

90
Entonces, sin tener que definir ningún método, una línea sería:[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.view action:@selector(endEditing:)]];
Subhas

8
@ParthBhatt agregué [tap setCancelsTouchesInView:NO];según la respuesta de @qiaoyi; Tuve un problema con una tabla que no responde a las selecciones de fila. 5 años después, espero que esto ayude a alguien más.
Tom Howard

77
Swift one-liner: self.view.addGestureRecognizer(UITapGestureRecognizer(target: self.view, action: #selector(UIView.endEditing(_:))))
Mal funcionamiento

176

Apreté algunas respuestas.

Use un ivar que se inicializa durante viewDidLoad:

UIGestureRecognizer *tapper;

- (void)viewDidLoad
{
    [super viewDidLoad];
    tapper = [[UITapGestureRecognizer alloc]
                initWithTarget:self action:@selector(handleSingleTap:)];
    tapper.cancelsTouchesInView = NO;
    [self.view addGestureRecognizer:tapper];
}

Descarte lo que esté editando actualmente:

- (void)handleSingleTap:(UITapGestureRecognizer *) sender
{
    [self.view endEditing:YES];
}

¡Fantástico, funciona en UITableView! ¡me salvó el día! Como nota al margen, usaré [UITextField resignFirstResponder] en lugar de [UIView endEditing:] porque tengo más UITextField y endEditing proporciona una posición de desplazamiento incorrecta incluso si el nuevo UITextField es visible.
Dr.Luiji

1
¡Muy mal porque el UITapGestureRecognizer nunca se agrega a la vista!

1
¿Cuál es el propósito de cancelsTouchesInView aquí?
Adam Johns

3
Si no agrega cancelsTouchesInView = false aquí, no podrá seleccionar otros tipos de elementos en su vista. Tus toques serán interceptados por el gestor de reconocimiento.
HalR

104

Mira esto, esta sería la forma más fácil de hacerlo,

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
      [self.view endEditing:YES];// this will do the trick
}

O

Esta biblioteca se encargará de incluir el desplazamiento automático de la barra de desplazamiento, tocar el espacio para ocultar el teclado, etc.

https://github.com/michaeltyson/TPKeyboardAvoiding


@Ramesh sí, pero no de esta manera. necesita crear una subclase de UITableView y dentro de esa clase implementar el método touchesBegan y luego llamar al método endEditing. ¡funciona! no olvide establecer la clase para su tabla en la punta con la clase recién creada.
Prasad De Zoysa

3
No oculta el teclado cuando el usuario toca otros controles a la vista. Ej: Tengo un UIButton y UITextField en UIView. Toco UITextField, luego toco el botón, el teclado no se esconde en este caso.
Jacob Dam

2
@JacobDam Tienes razón. El objetivo es renunciar al primer respondedor para ocultar el teclado si sucede algo fuera de un campo de texto.

88

Veo que algunas personas tienen problemas para usar el UITapGestureRecognizermétodo. La manera más fácil de lograr esta funcionalidad sin dejar intacto el comportamiento de toque de mi botón existente es agregar solo una línea a la respuesta de @ Jensen2k:

[tap setCancelsTouchesInView:NO];

Esto permitió que mis botones existentes siguieran funcionando sin usar el método de @Dmitry Sitnikov.

Lea sobre eso propertyaquí (busque CancelsTouchesInView): Referencia de clase de UIGestureRecognizer

No estoy seguro de cómo funcionaría con las barras de desplazamiento, ya que veo que algunos tenían problemas, pero espero que alguien más se encuentre con el mismo escenario que yo.


3
También me gustaría agregar, para aquellos que tienen una imagen de fondo en la parte posterior de la vista usando UIImageView, agregue [imageView setUserInteractionEnabled:NO];y haga clic en ella, lo que hace que este método funcione.
Paul Peelen

55

Es mejor hacer UIViewuna instancia de UIControl(en el generador de interfaces) y luego conectar su TouchUpInsideevento al dismissKeyboardmétodo. EstaIBAction método se verá así:

- (IBAction)dismissKeyboard:(id)sender {
    [aTextBox resignFirstResponder];
}

1
¡Gracias! Esto funcionó para mí y otras soluciones no. ( UITapGestureRecognizerinterferido con tocar botones dentro de la vista). touchesEndedno funcionó porque había un problema UIScrollViewcon la cadena de respuesta.)
jlstrecker

1
Esto funciona muy bien, pero debe agregarse a todo lo que desee que descarte el teclado. ¿Hay alguna manera de que un cuadro de texto renuncie automáticamente al primer respondedor al tocar cualquier otra cosa?
Isaac Overacker

44
No debería necesitar hacer de UIView un UIControl. Asegúrese de que UIView tenga habilitada la interacción del usuario.
Sofi Software LLC

1
@SofiSoftwareLLC Su sugerencia no funcionó para mí. Tuve que convertirlo en un UIControl incluso cuando se marcó la interacción de usuario habilitada.
tres tazas

1
Usando un StoryBoard cambié UIView a UIControl (donde habría seleccionado una subclase de UIView si hubiera creado una). Funciona bien. No me he encontrado con ningún problema. iOS8.
ToddB

30

Swift 4

Configure su UIViewControllercon este método de extensión una vez, por ejemplo, en viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()
    self.setupHideKeyboardOnTap()
}

y el teclado se cerrará incluso tocando el botón NavigationBar.

import UIKit
extension UIViewController {
    /// Call this once to dismiss open keyboards by tapping anywhere in the view controller
    func setupHideKeyboardOnTap() {
        self.view.addGestureRecognizer(self.endEditingRecognizer())
        self.navigationController?.navigationBar.addGestureRecognizer(self.endEditingRecognizer())
    }

    /// Dismisses the keyboard from self.view
    private func endEditingRecognizer() -> UIGestureRecognizer {
        let tap = UITapGestureRecognizer(target: self.view, action: #selector(self.view.endEditing(_:)))
        tap.cancelsTouchesInView = false
        return tap
    }
}

2
Bro, lo has clavado !! Esta respuesta es perfecta y funciona muy bien, muchas gracias.
óxido

28

Versión rápida, esto funciona en combinación con otros elementos (como uno UIButtonu otro UITextField):

override func viewDidLoad() {
    super.viewDidLoad()

    let tapper = UITapGestureRecognizer(target: self, action:#selector(endEditing))
    tapper.cancelsTouchesInView = false
    view.addGestureRecognizer(tapper)
}

1
el objetivo debería ser selfmás queself.view
EI Captain v2.0

1
el objetivo debe ser self.view. De lo contrario, el código anterior se bloqueará.
Naga Mallesh Maddali

canclesTouchesInViewEs una propiedad útil para usar. Gracias.
JonSlowCN

Los viejos hábitos tardan en morir. ¿Qué hace ese punto y coma aquí? ;)
Alexandre G.

@AlexandreG. De hecho, especialmente porque generalmente estoy codificando c#. FYI Ese punto y coma tiene sintaxis permitida, simplemente no es necesario.
Rob

17

Qué tal esto: Sé que esta es una publicación antigua. Podría ayudar a alguien :)

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {  
    NSArray *subviews = [self.view subviews];
    for (id objects in subviews) {
        if ([objects isKindOfClass:[UITextField class]]) {
            UITextField *theTextField = objects;
            if ([objects isFirstResponder]) {
                [theTextField resignFirstResponder];
            }
        } 
    }
}

No busqué UITextField, por lo que funciona para cualquier tipo de entrada. No veo ningún problema.
Frank

15

Esta es una buena solución genérica:

C objetivo:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.view endEditing:YES];    
}

Rápido:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    self.view.endEditing(true)
}

Basado en la solución @icodebuster: https://stackoverflow.com/a/18756253/417652


12

Swift 4 oneliner

view.addGestureRecognizer(UITapGestureRecognizer(target: view, action: #selector(UIView.endEditing(_:))))

Buen código, pero este desactiva la función de eliminación (-)
schellingerht

¡Eres un genio!
Abhishek Bedi

10

Creo que la forma más fácil (y mejor) de hacer esto es subclasificar su vista global y usar el hitTest:withEventmétodo para escuchar cualquier toque. Los toques en el teclado no están registrados, así que hitTest: withEvent solo se llama cuando tocas / desplazas / deslizas / pellizcas ... en otro lugar, luego llamas [self endEditing:YES].

Esto es mejor que usar touchesBeganporque touchesBeganno se llama si hace clic en un botón en la parte superior de la vista. Es mejor UITapGestureRecognizerque no reconocer un gesto de desplazamiento, por ejemplo. También es mejor que usar una pantalla tenue porque en una interfaz de usuario compleja y dinámica, no se puede poner la pantalla tenue en todas partes. Además, no bloquea otras acciones, no necesita tocar dos veces para seleccionar un botón en el exterior (como en el caso de a UIPopover).

Además, es mejor que llamar [textField resignFirstResponder], ya que puede tener muchos campos de texto en la pantalla, por lo que esto funciona para todos ellos.


Desafortunadamente, esto parece interferir con la 'X' de UISearchBar para borrar el texto.
huggie

1
Hay algunos problemas con este enfoque. por ejemplo, no puede desplazar una vista de desplazamiento sin perder el foco en su campo de texto. no es aconsejable para escenarios más complejos ... personalmente, prefiero la versión uicontrol de Dmitry, tal vez extendida por el comentario de Sofi Software.
katzenhut

Un ejemplo del desplazamiento se encuentra en la aplicación de correo electrónico, cuando escribe en la barra de búsqueda y luego desplaza la lista de correo, se cierra el teclado.
Enzo Tran

Es el mejor enfoque y lo había hecho para mis otros proyectos.
Chandramani


6

Si la vista está incrustada en absoluto UIScrollView, puede usar lo siguiente:

tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeOnDrag;
tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive;

El primero animará el teclado fuera de la pantalla cuando se desplaza la vista de la tabla y el segundo ocultará el teclado como la aplicación de Mensajes.

Tenga en cuenta que estos están disponibles en iOS 7.0 o superior.


6

Puede hacer esto usando el Storyboard en XCode 6 y superior:


Crea la acción para ocultar el teclado

Agregue esto al archivo de encabezado de la clase utilizada por su ViewController:

@interface TimeDelayViewController : UIViewController <UITextFieldDelegate>

- (IBAction)dissmissKeyboardOnTap:(id)sender;

@end

Luego agregue esto al archivo de implementación del mismo ViewController:

- (IBAction)dissmissKeyboardOnTap:(id)sender{
    [[self view]endEditing:YES];
}

Esta será ahora una de las 'Acciones recibidas' para su escena del guión gráfico (es decir, ViewController):

ingrese la descripción de la imagen aquí


Conecta la acción al evento del usuario

Ahora debe conectar esta acción al gesto del usuario de tocar el teclado.

Importante: debe convertir el 'UIView' que está contenido en su guión gráfico a un UIControl , para que pueda recibir eventos. Seleccione la vista de su jerarquía de escena del controlador de vista:

ingrese la descripción de la imagen aquí

... y cambia su clase:

ingrese la descripción de la imagen aquí

Ahora arrastre desde el círculo pequeño al lado de la 'acción recibida' para su escena, a una parte 'vacía' de su escena (en realidad está arrastrando la 'Acción recibida' al UIControl). Se le mostrará una selección de eventos a los que puede conectar su acción para:

ingrese la descripción de la imagen aquí

Seleccione la opción 'retocar dentro'. Ahora ha conectado la IBAction que creó a la acción del usuario de tocar el teclado. Cuando el usuario toca el teclado, ahora estará oculto.

(NOTA: Para enganchar la acción al evento, también puede arrastrar desde la acción recibida directamente al UIControl en la jerarquía de View Controllers. Se muestra como 'Control' en la jerarquía).


Gracias por la solución y la explicación detallada. Realmente útil para mi.
Yongxiang Ruan el

5

Si te entendí bien, quieres renunciar al teclado mientras tocas el lado textfieldpero no tienes referencia de tutextfield .

Prueba esto;

  • Tome global textField, llamémoslo reftextField
  • Ahora en textFieldDidBeginEditingestablecer campo de texto referenciado a

    - (void) textFieldDidBeginEditing:(UITextField *)textField{
        reftextField = textField;
    }
  • Ahora puede usarlo felizmente en cualquier reloj de botón (se recomienda agregar un botón transparente al comenzar a editar)

    - (void)dismissKeyboard {
          [reftextField resignFirstResponder];
    }
  • O para renunciar al botón hecho, intente esto.

    //for resigning on done button    
    - (BOOL) textFieldShouldReturn:(UITextField *)textField{
        [textField resignFirstResponder];
        return YES;
    }

3

Solo para agregar a la lista aquí mi versión de cómo descartar un teclado en el toque externo.

viewDidLoad:

UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.view addGestureRecognizer:singleTap];

En cualquier sitio:

-(void)handleSingleTap:(UITapGestureRecognizer *)sender{
    [textFieldName resignFirstResponder];
    puts("Dismissed the keyboard");
}

3

Un montón de excelentes respuestas aquí sobre el uso de UITapGestureRecognizer--todos de los cuales se rompe UITextFieldel botón claro (X). La solución es suprimir el reconocedor de gestos a través de su delegado:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    BOOL touchViewIsButton = [touch.view isKindOfClass:[UIButton class]];
    BOOL touchSuperviewIsTextField = [[touch.view superview] isKindOfClass:[UITextField class]];
    return !(touchViewIsButton && touchSuperviewIsTextField);
}

No es la solución más robusta, pero funciona para mí.


Exactamente, todo lo anterior falla si toco en el mismo campo de texto. Renuncia incluso el campo de texto es mi respondedor. y también cierra el teclado al tocar el botón de borrar dentro del campo de texto
Mrug

Me simplificarlo con sólo hacer la prueba para el botón: return !touchViewIsButton. Supongo que cualquier otro botón que deba descartar el teclado debería hacerlo en sus acciones. Además, es posible que no se llame a TouchUpInside cuando el diseño cambia al cerrar el teclado.
Marián Černý

3

Puede crear una categoría para UiView y anular los toques de inicio del método de la siguiente manera.

Me está funcionando bien y es una solución centralizada para este problema.

#import "UIView+Keyboard.h"
@implementation UIView(Keyboard)

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.window endEditing:true];
    [super touchesBegan:touches withEvent:event];
}
@end

3

Versión rápida de la respuesta de @ Jensen2k:

let gestureRecognizer : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: "dismissKeyboard")
self.view.addGestureRecognizer(gestureRecognizer)

func dismissKeyboard() {
    aTextField.resignFirstResponder()
}

Un trazador de líneas

self.view.addTapGesture(UITapGestureRecognizer.init(target: self, action: "endEditing:"))

2

Utilicé el ejemplo de Barry para mi nuevo desarrollo. ¡Funcionó muy bien! pero tuve que incluir un cambio leve, requerido para descartar el teclado solo para el campo de texto que se está editando.

Entonces, agregué al ejemplo de Barry lo siguiente:

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    _textBeingEdited = textField;
}
-(void) textFieldDidEndEditing:(UITextField *)textField
{
    _textBeingEdited = nil;
}

Además, cambié el método hideKeyboard de la siguiente manera:

- (IBAction)hideKeyboard:(id)sender
{
    // Just call resignFirstResponder on all UITextFields and UITextViews in this VC
    // Why? Because it works and checking which one was last active gets messy.
    //UITextField * tf = (UITextField *) sender;
    [_textBeingEdited resignFirstResponder];
}

2

Una de las formas más fáciles y cortas es agregar este código a su viewDidLoad

[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc]
                                     initWithTarget:self.view
                                     action:@selector(endEditing:)]];

2
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    if let touch = touches.first{
     view.endEditing(true)

     }
}

2

Intenté muchas de las respuestas aquí y no tuve suerte. Mi reconocedor de gestos de toque siempre causaba UIButtonsque no respondiera cuando lo tocaba, incluso cuando configurabacancelsTouchesInView propiedad del reconocedor de gestos en NO.

Esto es lo que finalmente resolvió el problema:

Tener un ivar:

UITapGestureRecognizer *_keyboardDismissGestureRecognizer;

Cuando un campo de texto comienza a editar, configure el reconocedor de gestos:

- (void) textFieldDidBeginEditing:(UITextField *)textField
{
    if(_keyboardDismissGestureRecognizer == nil)
    {
        _keyboardDismissGestureRecognizer = [[[UITapGestureRecognizer alloc]
                                       initWithTarget:self
                                       action:@selector(dismissKeyboard)] autorelease];
        _keyboardDismissGestureRecognizer.cancelsTouchesInView = NO;

        [self.view addGestureRecognizer:_keyboardDismissGestureRecognizer];
    }
}

Entonces el truco está en cómo configuras el dismissKeyboardmétodo:

- (void) dismissKeyboard
{
    [self performSelector:@selector(dismissKeyboardSelector) withObject:nil afterDelay:0.01];
}

- (void) dismissKeyboardSelector
{
    [self.view endEditing:YES];

    [self.view removeGestureRecognizer:_keyboardDismissGestureRecognizer];
    _keyboardDismissGestureRecognizer = nil;
}

Supongo que hay algo acerca de sacar la dismissKeyboardSelectorejecución de la pila de ejecución de manejo táctil ...



1

Esto funciona

En este ejemplo, aTextField es el único UITextField ... Si hay otros o UITextViews, hay un poco más por hacer.

// YourViewController.h
// ...
@interface YourViewController : UIViewController /* some subclass of UIViewController */ <UITextFieldDelegate> // <-- add this protocol
// ...
@end

// YourViewController.m

@interface YourViewController ()
@property (nonatomic, strong, readonly) UITapGestureRecognizer *singleTapRecognizer;
@end
// ...

@implementation
@synthesize singleTapRecognizer = _singleTapRecognizer;
// ...

- (void)viewDidLoad
{
    [super viewDidLoad];
    // your other init code here
    [self.view addGestureRecognizer:self.singleTapRecognizer];

{

- (UITapGestureRecognizer *)singleTapRecognizer
{
    if (nil == _singleTapRecognizer) {
        _singleTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapToDismissKeyboard:)];
        _singleTapRecognizer.cancelsTouchesInView = NO; // absolutely required, otherwise "tap" eats events.
    }
    return _singleTapRecognizer;
}

// Something inside this VC's view was tapped (except the navbar/toolbar)
- (void)singleTapToDismissKeyboard:(UITapGestureRecognizer *)sender
{
    NSLog(@"singleTap");
    [self hideKeyboard:sender];
}

// When the "Return" key is pressed on the on-screen keyboard, hide the keyboard.
// for protocol UITextFieldDelegate
- (BOOL)textFieldShouldReturn:(UITextField*)textField
{
    NSLog(@"Return pressed");
    [self hideKeyboard:textField];
    return YES;
}

- (IBAction)hideKeyboard:(id)sender
{
    // Just call resignFirstResponder on all UITextFields and UITextViews in this VC
    // Why? Because it works and checking which one was last active gets messy.
    [aTextField resignFirstResponder];
    NSLog(@"keyboard hidden");
}

1
- (void)viewDidLoad
{
    [super viewDidLoad]; 

UITapGestureRecognizer *singleTapGestureRecognizer = [[UITapGestureRecognizer alloc]
                                                          initWithTarget:self
                                                          action:@selector(handleSingleTap:)];
    [singleTapGestureRecognizer setNumberOfTapsRequired:1];
    [singleTapGestureRecognizer requireGestureRecognizerToFail:singleTapGestureRecognizer];

    [self.view addGestureRecognizer:singleTapGestureRecognizer];
}

- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
    [self.view endEditing:YES];
    [textField resignFirstResponder];
    [scrollView setContentOffset:CGPointMake(0, -40) animated:YES];

}

1

Agregue este código en su archivo ViewController.m :

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:YES];
}

1

En este caso, se puede usar ScrollView y agregarlo TextFielden ScrollView y quiero tocar ScrollViewy luego en Descartar el teclado. Traté de crear un código de muestra por si acaso. Me gusta esto,

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var scrollView: UIScrollView!
    @IBOutlet weak var textField: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.tap(_:)))
        view.addGestureRecognizer(tapGesture)
        // Do any additional setup after loading the view, typically from a nib.
    }
    func tap(gesture: UITapGestureRecognizer) {
        textField.resignFirstResponder()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Tu guión gráfico Mira eso al igual que.

ingrese la descripción de la imagen aquí


1

Puede usar el método UITapGestureRecongnizer para cerrar el teclado haciendo clic fuera de UITextField. Al usar este método cada vez que el usuario haga clic fuera de UITextField, el teclado se descartará. A continuación se muestra el fragmento de código para usarlo.

 UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]
                                   initWithTarget:self
                                   action:@selector(dismissk)];

    [self.view addGestureRecognizer:tap];


//Method
- (void) dismissk
{
    [abctextfield resignFirstResponder];
    [deftextfield resignFirstResponder];

}

1
  • Establecer los campos de texto delegado a la vista se cargó:

    override func viewDidLoad() 
    {
      super.viewDidLoad()
      self.userText.delegate = self
    }
  • Agregue esta función:

    func textFieldShouldReturn(userText: UITextField!) -> Bool 
    {
     userText.resignFirstResponder()
     return true;
    }
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.