Sidemenu: Missing ability to provide custom overlay

Created on 11 Nov 2019  路  4Comments  路  Source: jonkykong/SideMenu

New Issue Checklist


I have read the guidelines for contributing and I understand:

  • [x] My issue is happening in the latest version of SideMenu.
  • [x] My issue was not solved in the README.
  • [x] My issue can not be answered on stackoverflow.com.
  • [x] My issue is not a request for new functionality that I am unwilling to build and contribute with a pull request.
  • [x] My issue is reproducible in the demo project.

Issue Description

Is there a way to display custom overlay, like it was done in previous version using

        transition.overlayBlock = {[weak self] () -> UIView? in
            guard let strongSelf = self else { return nil }
            return strongSelf.activeDelegate?.sideMenuOverlay?(menu: strongSelf)
        }

Most helpful comment

Hi @vkolosovsky,

Currently, that's not explicitly supported although it's easy to incorporate. Two options:

  1. In your SideMenuNavigationController instance, override the viewWillAppear, etc. events to show your overlay.
  2. Create your own SideMenuPresentationStyle that shows your overlay during display.

Hope this helps.

All 4 comments

Hi @vkolosovsky,

Currently, that's not explicitly supported although it's easy to incorporate. Two options:

  1. In your SideMenuNavigationController instance, override the viewWillAppear, etc. events to show your overlay.
  2. Create your own SideMenuPresentationStyle that shows your overlay during display.

Hope this helps.

For those coming here looking for the solution, here is the code I used:

class subClass: SideMenuNavigationController {
    var overlayView:UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        //overlay creation
        overlayView = UIView()
        overlayView.backgroundColor = .shade1
        overlayView.alpha = 0.3
        overlayView.translatesAutoresizingMaskIntoConstraints = false
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        if let viewToInsertIn = presentingViewController?.view
        {
            viewToInsertIn.insertSubview(overlayView, at: viewToInsertIn.subviews.count)
            overlayView.leadingAnchor.constraint(equalTo: viewToInsertIn.leadingAnchor).isActive = true
            overlayView.trailingAnchor.constraint(equalTo: viewToInsertIn.trailingAnchor).isActive = true
            overlayView.topAnchor.constraint(equalTo: viewToInsertIn.topAnchor).isActive = true
            overlayView.bottomAnchor.constraint(equalTo: viewToInsertIn.bottomAnchor).isActive = true
        }

    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)

        overlayView.removeFromSuperview()
    }
}

@otusweb Your solution doesn't take presenting and dismissing animations into account. Here is a better solution:

import SideMenu
import UIKit

class MenuViewController: SideMenuNavigationController {
    private lazy var overlayView: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .gray
        view.alpha = 0.0

        return view
    }()

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        showOverlayView()
    }

    override func viewWillDisappear(_ animated: Bool) {
        hideOverlayView()

        super.viewWillDisappear(animated)
    }
}

extension MenuViewController {
    private func showOverlayView() {
        addOverlayView()

        UIView.animate(withDuration: presentDuration) {
            self.overlayView.alpha = 0.2
        }
    }

    private func hideOverlayView() {
        UIView.animate(withDuration: dismissDuration) {
            self.overlayView.alpha = 0.0
        } completion: { _ in
            self.removeOverlayView()
        }
    }

    private func addOverlayView() {
        guard let view = presentingViewController?.view else { return }
        view.addSubview(overlayView)

        NSLayoutConstraint.activate([
            overlayView.topAnchor.constraint(equalTo: view.topAnchor),
            overlayView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            overlayView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            overlayView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ])
    }

    private func removeOverlayView() {
        overlayView.removeFromSuperview()
    }
}

@jonkykong Thanks for the awesome library :clap:

Was this page helpful?
0 / 5 - 0 ratings