SWRevealViewController: elimina la interacción en la vista frontal cuando se revela la vista trasera

Necesito deshabilitar la interacción del usuario en la vista frontal cuando se muestra la vista posterior. Encontré algunos otros que preguntan lo mismo, pero no puedo realmente entender dónde o cómo implementar el código que he visto.

Ej: Encontré este código del enlace ,

- (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { if(position == FrontViewPositionLeft) { self.view.userInteractionEnabled = YES; } else { self.view.userInteractionEnabled = NO; } } - (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position { if(position == FrontViewPositionLeft) { self.view.userInteractionEnabled = YES; } else { self.view.userInteractionEnabled = NO; } } 

También encontré algunos otros enlaces

  • Link1
  • Link2
  • Link3

Tengo este código, pero no estoy realmente seguro sobre el lugar correcto para insert este código. He intentado agregarlo en mis vistas frontales / posteriores y también en el método SWRevealViewController sin éxito

Aprecio si alguien puede apuntarme en la dirección correcta.

    Recientemente he creado una solución que quería compartir (perdón si llega con 2 meses de retraso).

    Para deshabilitar la interacción del usuario en la vista frontal mientras el menu está abierto, agregué los siguientes códigos en mi MenuViewController :

    en la vista, aparecerá :

     [self.revealViewController.frontViewController.view setUserInteractionEnabled:NO]; 

    y en la vista Desaparecerá :

     [self.revealViewController.frontViewController.view setUserInteractionEnabled:YES]; 

    Esto deshabilitará todas las interacciones del usuario en el Controlador de vista frontal, lo que significa que los gestos deslizantes / pulsadores para CERRAR el menu también estarán DESACTIVADOS.

    Ahora, he creado un ParentViewController e hice que todos los controlleres de vista (los elementos del menu) fueran una subclass de ellos.

    en mi vista , LoadLoad , puse los siguientes códigos:

     SWRevealViewController *revealController = [self revealViewController]; [revealController panGestureRecognizer]; [revealController tapGestureRecognizer]; 

    Si ejecuta su aplicación en este punto, parecería que el Gesto Tap funciona (un toque en la Vista frontal cerrará el Menú), pero NO el Gesto Pan. No estoy seguro de por qué esto es así, pero para habilitar el gesto de la diapositiva para CERRAR su menu, agregue el siguiente código en MenuViewController :

    en la vista, aparecerá :

     [self.revealViewController.view addGestureRecognizer:self.revealViewController.panGestureRecognizer]; 

    Para resumir, esto es lo que necesita:

    En su MenuViewController :

     -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.revealViewController.frontViewController.view setUserInteractionEnabled:NO]; [self.revealViewController.view addGestureRecognizer:self.revealViewController.panGestureRecognizer]; } -(void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [self.revealViewController.frontViewController.view setUserInteractionEnabled:YES]; } 

    Y en el controller de vista de los elementos de menu (puede crear un ParentViewController para todos ellos):

     -(void)viewDidLoad { [super viewDidLoad]; SWRevealViewController *revealController = [self revealViewController]; [revealController panGestureRecognizer]; [revealController tapGestureRecognizer]; } 

    ¡Espero que esto ayude!

    He usado otro enfoque para lograr el mismo resultado, no estoy seguro si ayuda.

    Asigne SWRevealViewControllerDelegate a AppDelegate

     - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { SWRevealViewController* reveal = (SWRevealViewController*)self.window.rootViewController; reveal.delegate = self; // other bootstrapping code } 

    y luego en el método de delegado -(void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position siguiente manera:

     -(void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { if(position == FrontViewPositionLeft){ [revealController.frontViewController.view setUserInteractionEnabled:YES]; [revealController.frontViewController.revealViewController tapGestureRecognizer]; }else{ [revealController.frontViewController.view setUserInteractionEnabled:NO]; } } 

    ACTUALIZADO : agregó esta línea [revealController.frontViewController.revealViewController tapGestureRecognizer] para cerrar el controller revelado cuando pulse en frontviewcontroller

    Hey Guys as John Explained: Aunque estas soluciones funcionan, no creo que ninguna de ellas responda a la pregunta original, que en realidad es bastante simple:

    Hay dos pasos involucrados:

    1) Agregue los siguientes methods a su FrontViewController.m:

     - (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { if(position == FrontViewPositionLeft) { self.view.userInteractionEnabled = YES; } else { self.view.userInteractionEnabled = NO; } } - (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position { if(position == FrontViewPositionLeft) { self.view.userInteractionEnabled = YES; } else { self.view.userInteractionEnabled = NO; } } 

    2) Haga que su controller de vista frontal sea un delegado de SWRevealViewController en el file FrontViewController.h:

    (por ejemplo, @interface HomeViewController: UIViewController) donde mi FrontViewController se llamó HomeViewController

    y también en el file FrontViewController.m con lo siguiente en ViewDidLoad:

    self.revealViewController.delegate = self; ¡Problema resuelto! Mucho más fácil que crear classs padre, etc.

    Esto te ayudará a resolver las interacciones del usuario para el controller de FrontView encantador. Simplemente agregaría el siguiente cambio tomado de la respuesta de Xun también anterior y resolverás las interacciones del usuario y el menu ocultar cuando el usuario pulsa FrontViewController.

     - (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { if(position == FrontViewPositionLeft) { self.view.userInteractionEnabled = YES; } else { self.view.userInteractionEnabled = NO; } } - (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position { if(position == FrontViewPositionLeft) { self.view.userInteractionEnabled = YES; } else { self.view.userInteractionEnabled = NO; //Hides the menu when user taps FrontViewController [revealController.frontViewController.revealViewController tapGestureRecognizer]; } } 

    Agregue una subvista a la vista frontal cuando la vista trasera esté abierta.

    En el método viewWillAppear de su controller de elementos del menu, simplemente cree un button de superposition en la vista frontal y configure la acción para revelarToggle: of revealViewController

     -(void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; overlayView = [UIButton buttonWithType:UIButtonTypeCustom]; overlayView.frame = self.revealViewController.frontViewController.view.bounds; overlayView.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.8]; overlayView.tag = 999; [overlayView addTarget:self.revealViewController action:@selector(revealToggle:) forControlEvents:UIControlEventTouchUpInside]; [overlayView addTarget:self.revealViewController action:@selector(revealToggle:) forControlEvents:UIControlEventTouchDragOutside]; [self.revealViewController.frontViewController.view addSubview:overlayView]; } 

    En el método revealTogglle, quite el button de superposition si lo hay:

     - (void)revealToggleAnimated:(BOOL)animated { UIButton *overlayView = (UIButton*)[self.view viewWithTag:999]; if (overlayView) { [overlayView removeFromSuperview]; overlayView = nil; } // rest of the code... } 

    Aunque estas soluciones funcionan, no creo que ninguna de ellas responda a la pregunta original, que en realidad es bastante simple:

    Hay dos pasos involucrados:

    1) Agregue los siguientes methods a su FrontViewController.m :

     - (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { if(position == FrontViewPositionLeft) { self.view.userInteractionEnabled = YES; } else { self.view.userInteractionEnabled = NO; } } - (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position { if(position == FrontViewPositionLeft) { self.view.userInteractionEnabled = YES; } else { self.view.userInteractionEnabled = NO; } } 

    2) Haga que su controller de vista frontal sea un delegado de SWRevealViewController en el file FrontViewController.h :

     (eg @interface HomeViewController : UIViewController <SWRevealViewControllerDelegate>) 

    donde mi FrontViewController se llamó HomeViewController

    y también en el file FrontViewController.m con lo siguiente en ViewDidLoad:

     self.revealViewController.delegate = self; 

    ¡Problema resuelto! Mucho más fácil que crear classs padre, etc.

    Otra forma es tener una vista de superposition cuando se muestra la vista posterior. Puede usar esta biblioteca actualizada https://github.com/NSRover/SWRevealViewController y asegúrese de include shouldUseFrontViewOverlay = true cuando se muestre la vista posterior.

    Versión de Swift a @hardluckbaby respuesta:

    En MenuViewController ( controller de vista posterior ):

     override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) self.revealViewController().frontViewController.view.userInteractionEnabled = false self.revealViewController().view.addGestureRecognizer(self.revealViewController().panGestureRecognizer()) } override func viewWillDisappear(animated: Bool) { super.viewWillDisappear(animated) self.revealViewController().frontViewController.view.userInteractionEnabled = true } 

    En FrontViewController (puede hacer un ParentViewController para todos sus controlleres de vista frontal como dijo @hardluckbaby):

     override func viewDidLoad() { super.viewDidLoad() if let revealController = self.revealViewController() { revealController.panGestureRecognizer() revealController.tapGestureRecognizer() } } 
     On MenuTableViewController/ Rear VC, add SWRevealViewControllerDelegate. override func viewDidLoad() { super.viewDidLoad() self.revealViewController().delegate = self if self.revealViewController() != nil { self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer()) } } Add this delegate method. func revealController(revealController: SWRevealViewController!, didMoveToPosition position: FrontViewPosition) { if(position.rawValue == 4) { //move to rear self.revealViewController().frontViewController.view.userInteractionEnabled = false } else if (position.rawValue == 3) { //move to front - dashboard VC self.revealViewController().frontViewController.view.userInteractionEnabled = true } } func revealController(revealController: SWRevealViewController!, willMoveToPosition position: FrontViewPosition) { //will perform the same function as the above delegate method. } 
     class SideMenuViewController: UITableViewController { override func viewDidLoad() { super.viewDidLoad() self.revealViewController().delegate = self } } extension SideMenuViewController: SWRevealViewControllerDelegate { func revealController(revealController: SWRevealViewController!, willMoveToPosition position: FrontViewPosition) { if position == .Left { revealController.frontViewController.view.userInteractionEnabled = true } if position == .Right { revealController.frontViewController.view.userInteractionEnabled = false } } } 

    Considera la siguiente solución, funciona perfecto

     private let DimmingViewTag = 10001 extension UIViewController: SWRevealViewControllerDelegate { func removeInteractionFromFrontViewController() { revealViewController().delegate = self view.addGestureRecognizer(revealViewController().panGestureRecognizer()) } //MARK: - SWRevealViewControllerDelegate public func revealController(revealController: SWRevealViewController!, didMoveToPosition position: FrontViewPosition) { if case .Right = position { let dimmingView = UIView(frame: view.frame) dimmingView.tag = DimmingViewTag view.addSubview(dimmingView) view.bringSubviewToFront(dimmingView) } else { view.viewWithTag(DimmingViewTag)?.removeFromSuperview() } } } 

    Uso simple en UIViewController :

     override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) removeInteractionFromFrontViewController() } 

    Además de la respuesta hardluckbaby .

    Si ejecuta su aplicación en este punto, parecería que el Gesto Tap funciona (un toque en la Vista frontal cerrará el Menú), pero NO el Gesto Pan. No estoy seguro de por qué esto es así, pero para habilitar el gesto de la diapositiva para CERRAR su menu, agregue el siguiente código en MenuViewController:

    en la vista, aparecerá:

     [self.revealViewController.view addGestureRecognizer:self.revealViewController.panGestureRecognizer]; 

    Añade un comportamiento no deseado, por ejemplo, el gesto de pan cerrará la vista trasera cuando se inicia en él.

    El gesto de paneo pnetworkingeterminado puede no funcionar si lo agrega a su propia vista en algún lugar, algo así como en la vistaDidLoad de su controller de vista frontal:

     [self.view addGestureRecognizer:self.revealViewController.panGestureRecognizer]; 

    Elimine dichas líneas y esto debería funcionar como se esperaba, para gestos de pan y toque

     SWRevealViewController *revealController = [self revealViewController]; [revealController panGestureRecognizer]; [revealController tapGestureRecognizer]; 

    Estaba usando las funciones viewWillAppear y viewWillDisappear, pero como tengo subviews para casi todos los elementos del menu lateral que tenía. Mi problema fue que tenía un campo de input activo (visualización del keyboard) y accedí al menu lateral. En el menu raíz, el keyboard se ocultó pero luego de ingresar un submenu apareció nuevamente el keyboard. Para resolver esto, cambié el enfoque para habilitar y deshabilitar la interacción en revealController así:

     - (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position { if (position == FrontViewPositionRight) { [self.revealViewController.frontViewController.view setUserInteractionEnabled:NO]; } else if (position == FrontViewPositionLeft) { [self.revealViewController.frontViewController.view setUserInteractionEnabled:YES]; } } 

    En primer lugar, simplemente configure su delegado: self.revealViewController.delegate = self; y el método de delegado se dan a continuación:

     - (void)revealController:(SWRevealViewController *)revealController willMoveToPosition:(FrontViewPosition)position { static NSInteger tagLockView = 123456789; if (revealController.frontViewPosition == FrontViewPositionRight) { UIView *lockView = [self.view viewWithTag:tagLockView]; [UIView animateWithDuration:0.3 animations:^{ lockView.alpha = 0; } completion:^(BOOL finished) { [lockView removeFromSuperview]; }]; } else if (revealController.frontViewPosition == FrontViewPositionLeft) { UIView *lockView = [[UIView alloc] initWithFrame:self.view.bounds]; lockView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; lockView.tag = tagLockView; lockView.backgroundColor = [UIColor blackColor]; lockView.alpha = 0; [lockView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self.revealViewController action:@selector(revealToggle:)]]; [self.view addSubview:lockView]; [UIView animateWithDuration:0.3 animations:^{ lockView.alpha = 0.5; }]; } } 

    Swift 3.0 método simple y rápido.

    Código frontviewcontoller aquí …

     override func viewDidLoad() { super.viewDidLoad() if self.revealViewController() != nil { let rewel:SWRevealViewController = revealViewController() rewel.panGestureRecognizer() rewel.tapGestureRecognizer() } } 

    Código SideDrowerviewcontoller aquí …

     override func viewWillAppear(_ animated: Bool) { let rewel = self.revealViewController() rewel?.frontViewController.view.isUserInteractionEnabled = false rewel?.frontViewController.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer()) } override func viewWillDisappear(_ animated: Bool) { let rewel = self.revealViewController() rewel?.frontViewController.view.isUserInteractionEnabled = true }