I’ve been thinking quite a bit about how to be proactive in the practice of design. It seems as if this is more relevant today than ever, with the increasing responsibility of designers to make things that won’t harm people or their minds.
What is proactive work? Depends on your job.
For a chef, it may mean sourcing local ingredients before writing the menu.
A record producer may seek out up-and-coming talents to anticipate trends.
Photographers often shoot photos already knowing which edits they will apply later.
When good programmers write code they also anticipate change, so they make it as extensible and flexible as possible.
Architects never start designing a structure without understanding its location, purpose, and inhabitants.
So, what does it mean to do proactive work as a designer?
Just like a chef, we have to source ingredients (knowledge and context) before designing a product. We have to anticipate trends in the industry and know when to follow them, and maybe more importantly, when not to follow them. We have to prepare for how our designs will change with future requirements and when real users interact with them. We have to design responsibly, considering edge cases and social impact. And of course, to design well, we need to be informed about the contexts in which our work will be used.
In short, proactive design is design that takes its time to prepare for the side effects of real life.
That form you designed may not work on mobile browsers. That new feature you built might increase profit, but does it harm your user’s quality of life? Does your design system scale when you add a new feature to your product?
Designing proactively takes time, attention, and having the power to say no (or maybe “not yet”) to certain stakeholders. And if you’re not being proactive, you may not be doing your due diligence as a designer.
Designers today spend far too much time drawing rectangles and dragging them around the screen. Even designers who don’t know this kind of do know it, I think. Perhaps there is a point in every designer’s career (there certainly was for me) when the idea of design becomes less about aesthetics and more about structure.
When this happens, you’re forced to ask yourself questions about your process and how it serves the function of creating a cohesive, flexible, and supportive structure for your work. Once you move past aesthetics as your primary objective, you start to wonder why you’re manipulating shapes and colors by hand? Design is meant to function on our behalf, and instead so many designers spend their time functioning on behalf of their designs. I think this is backwards, and I think it doesn’t have to be this way.
I spent the first part of my career as a designer like most others—manipulating rectangles on a screen. Now, my day is spent writing code to manipulate those rectangles for me. At my current job, my role is dedicated to making design easier for both designers and developers. Building, maintaining, and improving upon our design systems and pattern libraries is done to enable better solutions to common problems with quicker execution times.
Pattern libraries and design systems don’t appear from nowhere—they have to be built and maintained. This process and all of its subprocesses all boil down to designers and developers making a series of decisions through a continued conversation. My job is to ask myself how I can facilitate those conversations and extract decisions from them more efficiently.
A design system has a lot of goals, but I think the most righteous of those is that it gives designers the ability to stop drawing their designs and write them instead. I propose that we start thinking of design systems as a vocabulary that we use to write design. Think about it: vocabularies have a shared origin like designers have shared inspiration and design has trends; vocabularies of the same language vary colloquially from place to place like our designs vary even internally. The artifacts representing our pattern libraries act like a dictionary—they’re a tool we used to understand the vocabulary. Additionally, the meaning of the words in our dictionary is not always derived from hard and fast rules. Sometimes people themselves can alter or change meanings entirely based on context.
Design systems, like vocabularies, are hard to maintain because they’re defined by people, and people are not consistent. That doesn’t mean they’re not worth it. Both (most of the time) allow us humans to communicate both verbally and visually with shared meaning and understanding. They allow us to categorize the things in our world, and to make statements that represent our values. Just like a vocabulary allows us to avoid communicating with charades, a design system allows designers to stop spending their time drawing pictures of a design, and instead use a common language to write what a design should look like and how it should function.
Like most good things, there are challenges. How can we create a concise vocabulary that simultaneously provides coverage over all of the things we need to express? How can the meaning of words be altered in a way that is natural and works for everyone? At what point do we alter the definition of a word whose meaning has changed based on cultural factors?
The hardest part of doing this successfully is making decisions. Getting a large group of people to agree on how things should be done is really tough, and it only gets tougher as your team grows. Doing this right involves aligning values, goals, ideas, etc. across teams, but that can often take a lot of time away from shipping feature work that, frankly, a lot of teams simply don’t have to spare. I think that a part of the solution to this is to have a team dedicated to aligning values, maintaining consistency, and advocating for a shared vocabulary between designers and developers. At my current job, we call this team the Design Developers. Whatever you want to call them, the design devs spend their days being the shepherds of the organization’s design system, and have the skills to translate decisions into actual tools for designers and developers to expedite their day-to-day work.
What’s great about thinking of product design as a form of writing using a bespoke vocabulary instead of drawing is that the handoff between designers and developers becomes a conversation instead of the delivery of an ephemeral artifact. Designers no longer have to spend their time recreating designs over and over using outdated tools, and instead can use that time to think about how the system can be usable, accessible, and delightful. They can work with design developers to improve the system for everyone instead of the parts of the product that their work touches. And developers can of course spend more time sweating the details rather than recreating work that’s no doubt been done elsewhere already.
The key to conversations is that they go both ways. For these ideas to work in practice, there must be a way for the conversation to evolve naturally and affect the vocabulary, just like our own conversations change the meaning of the words we use over time. Changes to the system must be vetted, purposeful, and most importantly, they must be communicated to everyone who uses the system. If the meaning of a word changes unexpectedly, the conversation becomes mute. That’s why we need to be careful and considered in the words we choose in order to ensure our conversations are timeless within the scope in which we’re working.
The process of governing a design system or a vocabulary varies too widely from company to company and culture to culture to say definitively what the correct solution is. There are plenty of resources out there from companies that have done this successfully, and although they are helpful, none of them will work for you out of the box. Doing this correctly involves remaining vigilant, treating everyone in your organization as a designer, and establishing vetted processes.
I encourage all designers (especially those working on bigger products with a team) to start looking at themselves as writers who are trying to articulate the solutions to problems. It is only when designers condition their colleagues to work with them in this way that design can become more than just wrangling rectangles.
When developing an iOS app, you often need to adjust constraints in order to make sure that the keyboard doesn’t obscure any of the elements on screen. This is a common problem that is an easy but annoying fix.
A few days ago I came across this Medium article by Roy McKenzie about a Swift protocol called KeyboardAvoidable that makes this process so much easier.
To sum it up quickly, any view controller that needs to adjust constraints in response to the keyboard hiding/showing just needs to conform to this protocol and then provide an array of constraints that need to be adjusted. The protocol extension has default methods that can be called when the controller is presented to add keyboard observers, and vice versa when the controller is dismissed.
With this short bit of code (available ion a Gist at the end of the post), all you would need to do to get this behavior is hook up outlets to the constraints of the views that need to be adjusted (probably the bottom constraint of a scroll view), stick them in an array, and implement the requirements of the protocol. When the keyboard is shown, your constraints will all be adjusted and animated. Sweet.
This ideas is so incredibly cool and useful and awesome and I plan to use it in every single project that requires this kind of behavior. What’s better is that the code is very easy to understand and modify for your specific needs.
After seeing this, it got me thinking about other ways protocols can be used to add default behaviors to views by injecting constraints. Every constraint you create in IB is of type NSLayoutConstraint, which means we can create very generic and reusable code very easily. Natasha the Robot has a great post about protocol-oriented views in Swift that is similar to this, except she isn’t using constraints. In that post, she demonstrated adding animations like shaking to views using protocols so that this functionality can be reused.
In a project I am working on, I have some views inside of a view controller that need to be toggled between being hidden or shown when the user tap’s a button. In addition, I want the view to animate into and off of the screen when it is toggled.
Originally, I was just creating outlets to the constraints on these views that I wanted to collapse upon and then putting all of the toggling logic into a method in my view controller that would get called when a button was tapped. This led to a lot of repeated code. For every collapsible view in my view controller, I was essentially writing the exact same code with slight variations to change which constraint I was collapsing upon. After seeing Roy’s KeyboardAvoidable protocol, I realized there was a much better way.
I started by making a protocol to represent collapsible views:
protocol Collapsible {
var collapseConstraint: NSLayoutConstraint? { get set }
func collapseView()
func showView()
func isCollapsed() -> Bool
}
The collapseConstraint variable is the constraint that we want our view to collapse upon. I made this optional because there could be a situation where we want to use one of these views without the collapsing functionality, and in that case we just won’t set this variable and it will default to nil. The collapseView() and showView() methods are called when we tap our button, and the isCollapsed() method just returns a bool letting us know what state we’re in.
Next, I created an extension for my Collapsible protocol that defined my default implementations of those methods. I constrained my extension to only apply to UIView objects:
extension Collapsible where Self: UIView {
func collapseView() {
collapseConstraint?.constant = -(self.frame.size.width)
}
func showView() {
collapseConstraint?.constant = 0
}
func isCollapsed() -> Bool {
return !(collapseConstraint?.constant == 0)
}
}
In my app, these view’s will be sliding into and off of the screen from the left or the right, so the collapseView() method set’s the constant of the collapse constraint to the negative value of the width (that way the view is entirely off screen). The showView() method sets the constant to 0, so that the view is pinned to the left or right edge. These methods will obviously need to be customized depending on which direction you want your view’s to collapse. If you wanted to get really fancy, you could set the direction as well as the constraint so that you can collapse in any direction with this one protocol.
The next step is just to create a view that conforms to the protocol, and declare our collapseConstraint variable:
class MyView: UIView, Collapsible {
var collapseConstraint: NSLayoutConstraint?
}
In my app, I am putting my views into my controller using Interface Builder. So inside of my controller I just create an outlet to the view and to the constraint that I want to collapse upon (trailing for right edge or leading for left edge), and in viewDidLoad() I set the collapseConstraint variable:
class MyViewController: UIViewController {
@IBOutlet var myView: MyView!
@IBOutlet var myViewLeadingConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
myView.collapseConstraint = myViewLeadingConstraint
}
}
The only thing left to do is put in a method that gets called when you tap a button (or take some other action):
func buttonTapped() {
if myView.isCollapsed() {
myView.showView()
}
else {
myView.collapseView()
}
UIView.animateWithDuration(0.3) {
self.view.layoutIfNeeded()
}
}
I put in the animation block in order to make the constraint change animate over a given time.
Building protocols like these make creating repeated behaviors extremely simple, and IB constraints fit so perfectly into this method. I am using this technique in several places, and I highly recommend it.
There has been a lot of talk about this article, which outlines Pixar’s 22 rules of storytelling. They are all great tips, but a few of them in particular stand out as all-purpose rules that not only apply to animation, but also writing.
You gotta keep in mind what’s interesting to you as an audience, not what’s fun to do as a writer. They can be very different.
When first deciding what I should write, I first ask myself what I would enjoy reading. If you write about something that you are interested in, your writing will benefit. Truly caring about your subject matter is the first step to making great stuff.
Sometimes writers are tempted to write what would be easier. Instead, they should write about what they would want to read. Because whoever reads your stuff does so because they are interested in the same things as you are. Writing about your interests will benefit your writing and your readers.
Come up with your ending before you figure out your middle. Seriously. Endings are hard, get yours working up front.
The most important part of writing is to have a message. Deciding what you want to say before you say it is essential to making a clear point. Using as few words as possible to convey the meaning of your words is almost always the way to go. I hate reading writers who beat around the bush before they finally make their point. Be clear and concise and your message will come across much stronger.
Also, be sure that you have an ending to write. Have a point to make. Have an end goal to accomplish. That will make writing everything before the ending a lot easier.
Why must you tell THIS story? What’s the belief burning within you that your story feeds off of? That’s the heart of it.
Although having something to write about is important, it’s also important to understand why you want to write about your topic in the first place. Why is this something you need to tell people? Why would they even care? Motivated writing is good writing. Don’t just have something to say, have the reason and desire to say it.
No work is ever wasted. If it’s not working, let go and move on – it’ll come back around to be useful later.
If you write something and decide to scrap it because you think it is terrible, do not feel as though you have wasted your time. Writing is hard. And the only way to become good at writing is to write. No matter what you are writing, good or bad, it is practice in expressing your thoughts and ideas. It is all worth it.
A good way to practice writing without worrying about quality is to keep a journal. I like to use Day One.
Writing is essentially storytelling, and the people at Pixar are some of the best storytellers I know. Therefore, it would be very wise to apply their principles to our work.
There is a quote that says “The man who can read and chooses not to is no better than the man who cannot read at all.” If we don’t seek to better ourselves and our work we can never hope to set ourselves apart from not only others in our respective fields, but anyone at all. If you write, you have to make an effort to get better. Learning from others is the best way I can think of to do that.