Search code examples
swiftuiviewuiviewcontrollerdelegatesprotocols

Delegates/Protocols between UIView & UIViewController not working


I'm working on a project where I'm trying to run some delegates/protocols between an UIView and an UIViewController. I've got some other delegates/protocols to run in this project, but there's one that I am super stumped on.

I've searched through Google and SO but haven't found a solution yet so I'm hoping someone can help me out here.

Here's a snippet of my UIView...

class SideMenuHomeView: UIView {

var expansionState: SideMenuExpansionState!
var mapController: MapController!

enum SideMenuExpansionState {
    case NotExpanded
    case Expanded
}

 override init(frame: CGRect) {
    super.init(frame: frame)
    let mapController = MapController()
    mapController.menuDelegate = self
    expansionState = .NotExpanded
}   

func handleSideMenuToggle() {
    if expansionState == .NotExpanded {
        animateInputView(targetPosition: self.frame.origin.x + 300) { (_) in
            self.expansionState = .Expanded
        }
    }
}

extension SideMenuHomeView: SideMenuHomeDelegate {
    func handleSideMenuHome() {
         handleSideMenuToggle()
    }
}

Here's a snippet of my UIViewController...

class MapController: UIViewController {

    var menuDelegate: SideMenuHomeDelegate!

    @objc func handleOpenMenu() {
        menuDelegate?.handleSideMenuHome()
    }
}

Here's my Protocol.swift...

protocol SideMenuHomeDelegate {
    func handleSideMenuHome()
}

Adding SideMenuHomeView to MapController

func configureSideMenuHomeView() {
    sideMenuHomeView = SideMenuHomeView()
    view.addSubview(sideMenuHomeView)
    sideMenuHomeView.anchorwithConstant(top: view.topAnchor, bottom: view.bottomAnchor, leading: view.leadingAnchor, trailing: nil, paddingTop: 0, paddingBottom: 0, paddingLeading: -(view.frame.width - 20), paddingTrailing: 0, width: view.frame.width, height: 0)
}

What I'm trying to achieve is for the UIView to shift 300 pixels on the X-axis to the right when I tap a button on the UIViewController.

When I connect my animate code block to a button on the UIView, it works, so it's not that. I've figured it out to be my delegate/protocol code, but can't figure out what is wrong with it.

Would anyone happen to know what's wrong with my current code? And is there a suggested/better way of communicating between a UIView and a UIViewController?

Thanks!


Solution

  • Your issue will be fixed if you set delegate while adding SideMenuHomeView as below,

    func configureSideMenuHomeView() {
        sideMenuHomeView = SideMenuHomeView()
        view.addSubview(sideMenuHomeView)
        self.menuDelegate = sideMenuHomeView
        sideMenuHomeView.anchorwithConstant(top: view.topAnchor, bottom: view.bottomAnchor, leading: view.leadingAnchor, trailing: nil, paddingTop: 0, paddingBottom: 0, paddingLeading: -(view.frame.width - 20), paddingTrailing: 0, width: view.frame.width, height: 0)
    }
    

    But you are using wrong delegation here. When you have instance of SideMenuHomeView then you don't need its delegate reference explicitly as you already have all the methods on the instance. It's like two references to same object.