按钮目标方法逻辑应该在 UIView 还是 UIViewController 中定义

Should the button target method logic be defined in UIView or UIViewController

我在 UIView Class 中定义了一个按钮和一个文本视图。按下时将发出网络请求。我应该在 UIView 或 UIViewController 中添加 button.addTarget 吗? MVC 的方法是什么。

class MessageInputView: UIView {

    let send_button: UIButton = {
        let button = UIButton()
        button.translatesAutoresizingMaskIntoConstraints = false
        button.backgroundColor = .red
        button.setTitle("Send", for: .normal)
        button.setTitleColor(UIColor.black, for: .normal)
        return button
    }()

    let textView: UITextView = {
        let textView = UITextView()
        textView.translatesAutoresizingMaskIntoConstraints=false
        textView.clipsToBounds = true
        textView.layer.cornerRadius = 19.5
        textView.layer.borderWidth = 1
        textView.layer.borderColor = UIColor.inputTextViewColor.cgColor
        return textView
    }()
}


class ChatMessagesViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

    let messageInputView = MessageInputView()
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
        messageInputView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(messageInputView)
        setMessagesInputViewConstraints()
    }

}

让我们看看模型、视图和控制器之间的区别。

  1. 视图 是用户与应用程序交互的方式。它应该 关注从用户获取输入数据并将输出数据发送给用户。任何其他操作都应该委托给不是视图的东西。
  2. 模型 是应用程序处理其所需操作的方式。它不应该知道或关心 how/where 正在使用这些操作的结果。它只是执行请求的操作,然后 returns 将结果发送给请求者。
  3. 控制器 是在视图和模型之间建立通信pathways/adapters 的东西。它是唯一知道视图和模型都存在的实体;他们不应该知道彼此或控制器的存在,因为他们不必关心它。他们所需要的只是一个适配器,允许他们与控制器提供的一些外部实体进行通信。

鉴于此信息,我认为您的按钮在单击时应该向通过其适配器处理其请求的事物发出请求。该适配器将请求路由到模型,该模型执行操作并 returns 结果。因此,视图对其请求的去向或响应的来源一无所知,并且模型不知道视图是请求操作和响应的视图。这保留了封装。

如果您的视图元素有自定义 class,您应该在 class 中声明 IBAction,但逻辑应该发生在视图控制器(或其他负责的 class 在其他架构中)。

您可以通过委托模式或在闭包的帮助下建立视图和视图控制器之间的连接,以更适合您的代码的方式为准。

这里是闭包的例子:

class CustomView: UIView {
  // ...
  var buttonHandler: (() -> Void)?

  @IBAction func buttonAction(_ sender: UIButton) {
    buttonHandler?()
  }
  // ...
}

class ViewController: UIViewController {
  // ...
  override func viewDidLoad() {
    // ...
    customView.buttonHander = { print("User clicked the button") }
  }
}