Дизайн MVC в представлении iOS взаимодействует с Model — Swift — программно

#swift #model-view-controller #uiview #uipangesturerecognizer #programmatically

#swift #model-view-controller #uiview #uipangesturerecognizer #программно

Вопрос:

У меня есть вопрос относительно дизайна MVC в приложении iOS.

Предположим, что я установил UIView класс с этим распознавателем жестов:

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

Как вы можете видеть, целью жеста просмотра является само представление.
Теперь предположим, что в switch case .ended я хочу отправить данные в базу данных.

Поскольку я заставляю View (CardView) взаимодействовать с моделью (данными), нарушит ли это правила проектирования MVC? Является ли эта реализация дизайна кода неправильной в соответствии с MVC?

Ответ №1:

Да, это нарушает шаблон MVC. Только контроллер должен взаимодействовать с моделью. Ваш контроллер может выступать в качестве delegate CardView .

Вот как вы могли бы это исправить.

 protocol CardViewDelegate: class {
    func cardViewShouldSendDataToDatabase(_ cardView: CardView)
}

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

Затем вам нужно только настроить свой контроллер в соответствии с CardViewDelegate протоколом и реализовать cardViewShouldSendDataToDatabase , в котором вы будете взаимодействовать с моделью.

Комментарии:

1. Также я думаю, что одним из недостающих шагов в процессе является установка представления delegate на контроллер при создании представления в контроллере

2. Я тоже с этим не согласен. cardViewShouldSendDataToDatabase ? Представление карты не должно даже знать о существовании базы данных. Возможно, контроллер представления даже не должен знать.

3. Как бы вы это сделали @matt?

4. Вы можете назвать свой метод делегирования так, как хотите, конечно, на ваше усмотрение 😉

5. Я согласен с Мэттом в том, что вы должны называть свои методы на основе того, что они делают. Например, если вы собираетесь отклонить представление, когда завершится жест панорамирования, вы должны назвать его примерно так cardViewWillDismiss