Search code examples
iosswiftcosmicmindmaterial-swift

cosmicmind material swift MenuView not closing


I am using cosmicmind material swift library and am following the examples code to try to get the FAB MenuView working.

I have copied the code and added the buttons i want, to test i am just testing with 2 buttons. The problem I am facing is with the handleMenu function:

/// Handle the menuView touch event.
internal func handleMenu() {
    if menuView.menu.opened {
        menuView.close()
        (menuView.menu.views?.first as? MaterialButton)?.animate(MaterialAnimation.rotate(rotation: 0))
    } else {
        menuView.menu.open() { (v: UIView) in
            (v as? MaterialButton)?.pulse()
        }
        (menuView.menu.views?.first as? MaterialButton)?.animate(MaterialAnimation.rotate(rotation: 0.125))
    }
}

The full code for this UINavigationController:

import UIKit
import Material

class MyTeeUpsController: UINavigationController {
/// MenuView reference.
private lazy var menuView: MenuView = MenuView()

/// Default spacing size
let spacing: CGFloat = 16

/// Diameter for FabButtons.
let diameter: CGFloat = 56

/// Handle the menuView touch event.
internal func handleMenu() {
    if menuView.menu.opened {
        menuView.close()
        (menuView.menu.views?.first as? MaterialButton)?.animate(MaterialAnimation.rotate(rotation: 0))
    } else {
        menuView.menu.open() { (v: UIView) in
            (v as? MaterialButton)?.pulse()
        }
        (menuView.menu.views?.first as? MaterialButton)?.animate(MaterialAnimation.rotate(rotation: 0.125))
    }
}

/// Handle the menuView touch event.
internal func handleButton(button: UIButton) {
    print("Hit Button \(button)")
}


private func prepareMenuView() {
    //let w: CGFloat = 52
    var img:UIImage? = MaterialIcon.cm.add?.imageWithRenderingMode(.AlwaysTemplate)
    let button1: FabButton = FabButton()//frame: CGRectMake((view.bounds.width - w)-10, 550,w,w))
    button1.setImage(img, forState: .Normal)
    button1.setImage(img, forState: .Highlighted)
    button1.pulseColor = MaterialColor.blue.accent3
    button1.backgroundColor = MaterialColor.blueGrey.lighten1
    button1.borderColor = MaterialColor.blue.accent3
    button1.borderWidth = 1
    button1.addTarget(self, action: #selector(handleMenu), forControlEvents: .TouchUpInside)
    menuView.addSubview(button1)


    img = UIImage(named: "filing_cabinet")?.imageWithRenderingMode(.AlwaysTemplate)
    let button2:FabButton = FabButton()
    button2.depth = .None
    button2.setImage(img, forState: .Normal)
    button2.setImage(img, forState: .Highlighted)
    button2.pulseColor = MaterialColor.blue.accent3
    button2.borderColor = MaterialColor.blue.accent3
    button2.borderWidth = 1
    button2.backgroundColor = MaterialColor.blueGrey.lighten1
    button2.addTarget(self, action: #selector(handleButton), forControlEvents: .TouchUpInside)
    menuView.addSubview(button2)


    menuView.menu.direction = .Up
    menuView.menu.baseSize = CGSizeMake(diameter, diameter)
    menuView.menu.views = [button1,button2]
             view.layout(menuView).width(diameter).height(diameter).bottomRight(bottom: 58, right: 20)
    }
    private func prepareTabBarItem() {

        //todo
    }
    override func viewDidLoad() {
        super.viewDidLoad()
        prepareMenuView()
    }
}

The menu I have embedded as a subView of UINavigationController. The reason I have added to this subView is because the FAB is on top of a search/display controller (TableView) and this way the FAB can remain on top of the TableView even when scrolling the contents of the Table.

When the view initially loads, I can click on the menu button and the animation happens correctly and button2 appears. However, it does not allow me to hit the second button OR close the menu by pressing button1 again UNLESS I navigate to another tab in the tab bar controller and then navigate back to the tab where the FAB MenuView was located. I am loading my prepareMenuView() function in viewDidLoad just as it is shown in the example.

Not sure how to modify this so that it can behave as desired. It doesn't make sense to pick another ViewController lifecycle method to run prepareMenuView().


Solution

  • so the issue with your code is that button2 only has the selector handler for handleButton. The handleMenu handler is not added to it. So you have two solutions.

    1. Add the handleMenu call to the handleButton

    internal func handleButton(button: UIButton) { print("Hit Button \(button)") handleMenu(button) }

    1. Add a selector handler to the button2 instance for handleMenu.

    button2.addTarget(self, action: #selector(handleMenu), forControlEvents: .TouchUpInside) button2.addTarget(self, action: #selector(handleButton), forControlEvents: .TouchUpInside)

    Either option will work, just remember that order matters. So if you want the menu to close before you load some content, then call the method before or add the selector handler handleMenu before you add the handleButton.

    :) All the best!