Does a UIView object with an embedded UIButton and IBAction defy MVC principles?

Does a UIView object with an embedded UIButton and IBAction violate MVC principles?

Example:

class MyView: UIView {
    @IBOutlet weak var myButton: UIButton!

    @IBAction func myButtonTapped(sender: AnyObject) {
        // do something
    }
}

Are controllers the only objects that are supposed to perform actions? If so, what would be some common alternative patterns?

0

There are lots of different views on what exactly “MVC” patterns should look like but I’ll argue there’s nothing inherently wrong with controls triggering behavior on their parent view. However what that // do something function is responsible for is important.

Actions and outlets are tools for managing the configuration of a class spread across source and .xib files. Use of those alone tells you very little about what interface you have designed for a specific component and how appropriate the responsibilities of that component are.

My rule here is that a view class should accept some immutable state to display and emit messages about user intent but not be aware of or concerned with how the application responds to that intent. For example a view might report that a user wants to select or delete an item from a list, or increment a value, or submit a form. If those desires can be respected and how they are performed is not the view’s job. Inversely the view should not leak implementation details about how it determined the user’s intention. No other components need to know about what buttons exist within the view or where touches occurred. Done well this means that I could completely replace the implementation of the view with a new set of controls without changing any other part of the app.

It is therefore totally reasonable to have a view with internal IBActions in order to keep details of the view’s subview structure private and expose an appropriate interface to the rest of the app.

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *