tutorial sidemenu side how desplegable create bar ios objective-c swrevealviewcontroller

ios - sidemenu - SWRevealViewController cierra la vista posterior al tocar la vista frontal



slide out menu swift 4 (9)

Estoy usando SWRevealViewController para implementar un menú de navegación lateral en mi aplicación. Me gustaría hacerlo para que la vista frontal no pueda interactuar cuando se abre la vista trasera, excepto que cuando el usuario toca la vista frontal, la vista trasera se cerrará y la vista frontal se podrá interactuar nuevamente. Tengo estos dos métodos de delegado SWRevealViewController que actualmente eliminan la interacción de la vista frontal.

- (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; } }

Sin embargo, esto no hace que la vista trasera se cierre cuando se toca la vista frontal. ¡Cualquier ayuda sería muy apreciada, gracias!


  1. Subclase de SWRevealViewController .
  2. Implementar revealController:willMoveToPosition: de SWRevealViewControllerDelegate .
  3. Configure la vista de pantalla completa en el controlador de vista frontal para anular todos los toques.
  4. Añadir toque gesto reconocedor para ocultar el menú.

Muestra con buena animación:

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

Esta solución para la versión anterior 1.x SWRevealViewController.


Considera esta solución simple, funciona perfecto.

private let DimmingViewTag = 10001 extension UIViewController: SWRevealViewControllerDelegate { func setupMenuGestureRecognizer() { revealViewController().delegate = self view.addGestureRecognizer(revealViewController().panGestureRecognizer()) view.addGestureRecognizer(revealViewController().tapGestureRecognizer()) } //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) setupMenuGestureRecognizer() }


En ViewDidLoad de tu frontViewController debes agregar un UITapGestureRecognizer

SWRevealViewController *revealController = [self revealViewController]; UITapGestureRecognizer *tap = [revealController tapGestureRecognizer]; tap.delegate = self; [myView addGestureRecognizer:tap];

Esto debería hacer que la vista trasera se cierre cuando se SWRevealViewController la vista frontal, que es el comportamiento predeterminado de SWRevealViewController .


En su controlador de vista de menú , agregue esto:

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

Luego, en el Controlador de vista de elementos de menú , agregue esto en viewDidLoad :

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

También puedes ver mi respuesta here . Aborda el problema en la interacción de la vista frontal (más un gesto de diapositiva).


Gracias a y por su gran ayuda. Aquí está la versión Swift 4 que se deriva de ahí y te ahorra un par de horas:

extension UIViewController: SWRevealViewControllerDelegate { func setupMenuGestureRecognizer() { revealViewController().delegate = self view.addGestureRecognizer(revealViewController().panGestureRecognizer()) view.addGestureRecognizer(revealViewController().tapGestureRecognizer()) } //MARK: - SWRevealViewControllerDelegate public func revealController(_ revealController: SWRevealViewController!, willMoveTo position: FrontViewPosition) { let tagId = 112151 print("revealController delegate called") if revealController.frontViewPosition == FrontViewPosition.right { let lock = self.view.viewWithTag(tagId) UIView.animate(withDuration: 0.25, animations: { lock?.alpha = 0 }, completion: {(finished: Bool) in lock?.removeFromSuperview() } ) lock?.removeFromSuperview() } else if revealController.frontViewPosition == FrontViewPosition.left { let lock = UIView(frame: self.view.bounds) lock.autoresizingMask = [.flexibleWidth, .flexibleHeight] lock.tag = tagId lock.alpha = 0 lock.backgroundColor = UIColor.black lock.addGestureRecognizer(UITapGestureRecognizer(target: self.revealViewController(), action: #selector(SWRevealViewController.revealToggle(_:)))) self.view.addSubview(lock) UIView.animate(withDuration: 0.75, animations: { lock.alpha = 0.333 } ) } } }

Ahora llame a esta función setupMenuGestureRecognizer desde viewDidLoad de su controlador de vista posterior.

O también puede implementar SWRevealViewControllerDelegate directamente en su clase de controlador de vista posterior y usar la función SWRevealViewControllerDelegate en la propia clase.


Poner código debajo en el controlador de vista de menú funciona para mí

@interface SidebarTableViewController() { UIView* coverView; } - (void)viewWillDisappear:(BOOL)animated { [coverView removeFromSuperview]; //[self.revealViewController.frontViewController.view setUserInteractionEnabled:YES]; // get your window screen size } - (void)viewWillAppear:(BOOL)animated { // get your window screen size CGRect screenRect = [[UIScreen mainScreen] bounds]; //create a new view with the same size coverView = [[UIView alloc] initWithFrame:screenRect]; // change the background color to black and the opacity to 0.6 coverView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6]; // add this new view to your main view [self.revealViewController.frontViewController.view addSubview:coverView]; // [self.revealViewController.frontViewController.view setUserInteractionEnabled:NO]; }


Si está utilizando SWIFT, puede hacer algo como esto, en su frontViewController:

override func viewDidLoad() { super.viewDidLoad() if self.revealViewController() != nil { self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer()) self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer()) } }

El código funciona para los gestos TAP y PAN.


Usé el tapGestureRecognizer pero todavía hay algunos problemas. Intenté esto y trabajé muy bien!

Definir clase:

@interface IgnoreView : UIView @property (nonatomic, assign) BOOL shouldAllTouchesBeForMe; @end

Implementar:

@implementation IgnoreView - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { if( self.shouldAllTouchesBeForMe ){ return self; } return [super hitTest:point withEvent:event]; } @end

Luego haga su clase de Vista en Interface Builder de la clase IgnoreView

En su ViewController, entonces, haga:

en - viewDidLoad

self.revealViewController.delegate = self; [self.view addGestureRecognizer:self.revealViewController.tapGestureRecognizer];

El implemento en su controlador de vista también:

- (void)revealController:(SWRevealViewController *)revealController didMoveToPosition:(FrontViewPosition)position { IgnoreView *i = (id)self.view; i.shouldAllTouchesBeForMe = position == FrontViewPositionRight; }

¡Y ya está todo listo!


EDITAR: Cambiar la máscara automática de UIView para que se adapte a Swift 2, gracias al comment Marroc

Esta es la versión Swift-SWRevealViewController 2.x de la respuesta de @ avdyushin:

func revealController(revealController: SWRevealViewController!, willMoveToPosition position: FrontViewPosition) { let tagId = 4207868622 if revealController.frontViewPosition == FrontViewPosition.Right { let lock = self.view.viewWithTag(tagId) UIView.animateWithDuration(0.25, animations: { lock?.alpha = 0 }, completion: {(finished: Bool) in lock?.removeFromSuperview() } ) lock?.removeFromSuperview() } else if revealController.frontViewPosition == FrontViewPosition.Left { let lock = UIView(frame: self.view.bounds) lock.autoresizingMask = [.FlexibleWidth, .FlexibleHeight] lock.tag = tagId lock.alpha = 0 lock.backgroundColor = UIColor.blackColor() lock.addGestureRecognizer(UITapGestureRecognizer(target: self.revealViewController(), action: "revealToggle:")) self.view.addSubview(lock) UIView.animateWithDuration(0.75, animations: { lock.alpha = 0.333 } ) } }