Separating Views from ViewController

Alok Subedi
2 min readAug 11, 2021

--

ViewController in iOS is both view and controller, which makes it massive. Let’s separate View from ViewController.

We will use LoginFormViewController from my last article - MVC that is not massive. Although this is a continuation of that project, you can go through this one independently.

You can download the starter project from here if you want to follow along.

Project Overview

We will work with LoginFormViewController which has textfields with sigInButton. It was separated from LoginViewController in the last article. SignupViewController and HomeViewController are for navigation and DummyThirdPartyLogin fakes login with Facebook and Google.

LoginFormViewController

While, almost half of the LoginFormViewController is about handling views, it would be awesome if the controller does not have to care about views.

Separating View

The idea is very simple; we create a view class that is responsible for creating and laying out views, then we add this view to ViewController. We can make multiple views or a single view per ViewController.

  • Let’s start by creating a class LoginForm, which is a child of UIView. Copy all the views from LoginFormViewController with its creator methods.
  • Next, bring the addView and addConstraints methods and call it from init.
  • Let’s fix the issues now. First, make LoginForm a UITextFieldDelegate by copying the extension of LoginFormViewController.
  • We don’t have login function. Login is the responsibility of controller so we can not put it in view. We need to find a way to notify controller to call login. Let’s use closure this time.
    Create an optional variable login of type function that takes no parameter and returns void. For signInButton action, let’s create an objc function loginTapped that calls login that we just created.

Update LoginFormViewController

  • First, remove everything moved to LoginForm. Now create form of type LoginForm and add it to view and add constraints.
  • Setup the login variable of LoginForm. Make it a closure that calls login function in the controller.
  • Fix the issue in login function by creating computed properties username and password in LoginForm.

Now that we have successfully moved view to LoginForm, LoginFormViewController is a lot smaller. Let’s go a step further, instead of adding the LoginForm, let’s just make it the view of LoginFormViewController. Then, remove form.translatesAutoresizingMaskIntoConstraints = false from the form. Remove addViews and addConstraints functions and add view = form in viewDidLoad instead.

Exercise

LoginForm has a label and textField combo for username and password. Try creating a new view TextFieldWithLabel. While you are at it, try making label and textfield private by creating TextFieldWithLabelDelegate.

What Next?

If we look at login function, we can see it is huge and has multiple responsibilities. We can create different functions for validation and different for data task. Even better, different class with particular responsibilities.

Take your time learning one technique at a time.

--

--