SWRevealViewController закрывает вид сзади при нажатии на передний вид

Я использую SWRevealViewController, чтобы реализовать в навигаторе навигационное меню. Я хотел бы сделать так, чтобы вид спереди не мог взаимодействовать при открытии заднего вида, за исключением того, что когда пользователь нажимает вид спереди, заднее изображение закрывается, а вид спереди может снова взаимодействовать. У меня есть два метода делегирования SWRevealViewController, которые в настоящее время удаляют взаимодействие с переднего вида.

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

Однако это не приводит к закрытию заднего вида при нажатии на передний вид. Любая помощь будет принята с благодарностью, спасибо!

Ответы

Ответ 1

Если вы используете SWIFT, вы можете сделать что-то подобное в своем frontViewController:

override func viewDidLoad() {
    super.viewDidLoad()

    if self.revealViewController() != nil {

        self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
        self.view.addGestureRecognizer(self.revealViewController().tapGestureRecognizer())
    }

}

Код работает для жестов TAP и PAN.

Ответ 2

В ViewDidLoad вашего frontViewController вам нужно добавить UITapGestureRecognizer

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

[myView addGestureRecognizer:tap];

Это должно привести к закрытию заднего вида при нажатии на передний вид, который является SWRevealViewController поведением по умолчанию.

Ответ 3

РЕДАКТИРОВАТЬ: Изменить UIView autoresizingMask в соответствии с Swift 2, благодаря Marroc comment

Это версия Swift-SWRevealViewController 2.x ответа @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
            }
        )
    }
}

Ответ 4

  • Подкласс SWRevealViewController.
  • Внесите revealController:willMoveToPosition: из SWRevealViewControllerDelegate.
  • Установите полноэкранный режим на контроллере внешнего вида, чтобы переопределить все касания.
  • Добавить атрибут жестов жесты, чтобы скрыть меню.

Пример с приятной анимацией:

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

Это решение для старой версии 1.x SWRevealViewController.

Ответ 5

Рассмотрим это простое решение, отлично работает

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

Простое использование в UIViewController:

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

    setupMenuGestureRecognizer()
}

Ответ 6

Поместите ниже код в диспетчер меню, его работы для меня

@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];
}

Ответ 7

Благодаря mixth и avdyushin за возможную помощь. Здесь версия Swift 4, полученная оттуда, отвечает на сохранение вашей пары часов:

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
        }
        )
    }
}

}

Теперь вызовите эту функцию setupMenuGestureRecognizer из viewDidLoad вашего контроллера заднего вида.

Или вы также можете реализовать SWRevealViewControllerDelegate непосредственно в своем классе контроллера заднего вида и использовать функцию SWRevealViewControllerDelegate в самом классе.

Ответ 8

Я использовал tapGestureRecognizer, но все еще есть некоторые проблемы. Я пробовал это и отлично работает!

Определить класс:

@interface IgnoreView : UIView

@property (nonatomic, assign) BOOL shouldAllTouchesBeForMe;

@end

Реализация:

@implementation IgnoreView

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

@end

Затем создайте класс View в построителе интерфейса класса IgnoreView

В вашем ViewController выполните следующие действия:

in - viewDidLoad

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

в вашем контроллере view тоже:

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

И вы все настроены!

Ответ 9

В контроллере представления вашего меню добавьте следующее:

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

Затем в вашем диспетчере представлений элемента меню добавьте это в viewDidLoad:

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

Также проверьте мой ответ здесь. Он решает проблему взаимодействия с внешним видом (плюс жест слайдов).