swiftmodel-view-controlleruiviewuipangesturerecognizer

MVC design in iOS View talks to Model - Swift - Programmatically


I have a question regarding the MVC design in iOS application.

Suppose that I have set a UIView class with this gesture recogniser:

class CardView: UIView {        
    init(frame: CGRect) {
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePan(gesture:)))
        self.addGestureRecognizer(panGesture!)
    }
    
    @objc func handlePan(gesture : UIPanGestureRecognizer) {
        switch gesture.state {
        case .began:
            handleBegan(gesture)
        case .changed:
            handleChanged(gesture)
        case .ended:
            handleEnded(gesture)
            sendDataToDatabase()
        case .cancelled:
            turnCardBackToOrigin()
        default:
            break
        }
    }
}

As you can see the target of the view gesture is the view itself. Now suppose that in switch case .ended I want to send data to database.

Since I'm making View (CardView) talk with the model (Data), would this break the MVC designing rules? Is this code design implementation wrong according to MVC?


Solution

  • Yes it breaks the MVC pattern. Only the Controller should talk to the Model. Your Controller can act as a delegate to the CardView.

    This is how you could fix it.

    protocol CardViewDelegate: class {
        func cardViewShouldSendDataToDatabase(_ cardView: CardView)
    }
    
    class CardView: UIView{
        weak var delegate: CardViewDelegate?
        
        // ...
        
        func sendDataToDatabase() {
            delegate?.cardViewShouldSendDataToDatabase(self)
        }
    }
    

    Then you only have to make your Controller conform to the CardViewDelegate protocol and implement cardViewShouldSendDataToDatabase in which you would talk to the model.