PodSearch

Under the Radar

54: Parametric Design

 

00:00:00   Welcome to Under the Radar, a show about independent iOS app development.

00:00:04   I'm Mark Orment.

00:00:05   And I'm David Smith.

00:00:06   Under the Radar is never longer than 30 minutes, so let's get started.

00:00:10   So today we wanted to talk a little bit about design, to pull it back into something a little

00:00:18   more pretty I suppose.

00:00:20   To talk a little bit about a very low-level approach to design that I think we both take

00:00:25   in our apps and is something that I think can be really powerful once you start taking

00:00:30   this approach and start using it in all of your apps.

00:00:32   And it's something that I tend to call for myself parametric design, which is a very

00:00:37   fancy and nonsensical name to have for something like this.

00:00:40   But basically it's designing your app in such a way that large amount parts of the appearance,

00:00:47   of the layout, of the sort of the way that it will appear visually on the screen is controlled

00:00:53   by parameters and variables within your code.

00:00:57   To the degree that you can change a few numbers, change a few values, and you can radically

00:01:03   change the appearance of your application.

00:01:06   And this is something that I think works best if you do a lot of programmatic UI rather

00:01:11   than something like a storyboard where a lot of those values are baked into the storyboard

00:01:16   or baked into the nib.

00:01:17   But if you're doing any amount of your UI and code, it's possible to do a lot of this.

00:01:23   If you're doing it in storyboards and stuff, you can still do it there.

00:01:26   You're just going to have duplicated effort in a lot of places where you set a value in

00:01:30   your storyboard and then you also have somewhere in code that you can overwrite that value.

00:01:35   But either way, however you end up with it, if you design your app such that you can change

00:01:40   everything dynamically, it makes the development process, I think, much more fluid and is something

00:01:47   that I've found for myself helps me very quickly iterate on a design because usually what happens,

00:01:53   and this is something, the reason this topic is a friend of mine for me, is I'm going through

00:01:57   the layout and design phase of my next app.

00:02:00   And the way I tend to do this is I'll put a very basic, super simple, kind of horrendously

00:02:07   ugly design in place.

00:02:09   It has bad colors, it has bad fonts or sizes and weights, and I'm just trying to get it

00:02:16   sort of basically working.

00:02:18   And once I have that, I then want to go through and actually sort of adjust it and dial it

00:02:22   down.

00:02:23   And this is sort of the bottom-up design approach rather than if you're working with a professional

00:02:29   designer or somebody who's giving you a "here's what it should look like in the end" and you're

00:02:33   working from there down, obviously this isn't something that would work.

00:02:36   But if you're working it from the approach like me where you're starting with just basic

00:02:39   like, it's just the UI button that looks like a UI button, it's a UI label that just looks

00:02:43   like a UI label.

00:02:44   If you start there, and are working on it, if you build your app such that you can have

00:02:50   all these dials and hooks into it, then you can quickly change things.

00:02:54   And this is the approach that I tend to take, that when I'm actually iterating on my UI,

00:02:58   I'm just sitting there changing variables and then build and run, look at it, see how

00:03:02   it feels, run it on my device.

00:03:05   I've even seen people who do this where you actually build a method into the application

00:03:09   where if you quadruple tap on the screen with three fingers, a little UI pops up that you

00:03:15   can change the values while the app is live and running.

00:03:19   But it's an approach I think that is a way of thinking about your app at a level that

00:03:24   gives you that flexibility.

00:03:25   And ultimately it probably even makes your app better from a testability or, not that

00:03:31   I really write tests, but from an ability to understand what's going on perspective,

00:03:36   because everything that's in the app, everything about the way it looks is explicitly written

00:03:42   out somewhere, because it's a variable whose value you can change.

00:03:46   Yeah, I mean this is the kind of thing, I've designed Overcast from day one to be this

00:03:51   way in many ways, and this can start with very simple things.

00:03:55   It can start with something like text sizes and whether your app has a light or dark theme.

00:04:01   And if you make all this managed by some kind of central class, like in Overcast it's called

00:04:06   OC Appearance, because it goes beyond what UI Appearance offers, although OC Appearance

00:04:12   manages the UI appearance.

00:04:14   But OC Appearance is just my centralized class that listens for notifications for things

00:04:19   like the dynamic text size preference changing, and then it posts, it basically reposts a

00:04:26   notification to all my custom controls and classes and controllers and everything.

00:04:32   They all listen for the OC Appearance did change notification, and then they set their

00:04:38   own layouts accordingly.

00:04:40   And when you take this kind of approach, this makes it way easier to do things like support

00:04:45   dynamic type, or support a dark mode, or alternate color schemes, or to support certain accessibility

00:04:51   options like bold text or button shapes.

00:04:55   So there's lots of different things you can do once you have this kind of centralized

00:05:00   design and appearance and theme manager infrastructure.

00:05:05   And so, and one of the things I've done is very simply, I've created, if you have some

00:05:11   kind of control or screen or area where you have a background, you can assume that background

00:05:17   will probably be white by default on most things.

00:05:19   In Overcast, I make that an OC background view, which is a custom UI view subclass that

00:05:24   literally just listens to the OC Appearance did change notification and sets itself to

00:05:28   be the current theme's background color.

00:05:31   And that way, it's very, very easy for me to not only change the design, but to implement

00:05:36   dark mode.

00:05:37   And so I can test out all sorts of colors and things very easily, and then every background

00:05:42   in my app automatically changes with this custom OC background view.

00:05:46   Similar, I have OC button, I have OC border button for all the little round erect buttons

00:05:50   I have in Overcast.

00:05:51   It's all a standard class that automatically customizes its own appearance whenever the

00:05:55   appearance changes and can respond to all these different values and everything, both

00:05:59   dynamically or originally in the code, like you were saying.

00:06:02   I also have an OC styled label, and this is one of my most used and biggest time saver

00:06:08   UI things I've ever done, is the OC styled label.

00:06:12   And basically, it's a UI label subclass, like the other ones, it manages its own appearance

00:06:17   and its own parameters and everything, based on the current Overcast theme, whether it's

00:06:23   dark mode or whatever.

00:06:24   But the OC styled label takes as its main parameter the UI font text style, which is

00:06:30   just like if you're picking a UI font, you can call the preferred font with whatever

00:06:35   the full method name is, preferred font with style UI font text style.

00:06:39   These are all the iOS 7 and above built-in text styles.

00:06:41   You have headline, body, caption one, caption two, stuff like that.

00:06:45   And in my OC styled label, I can just create one of these instances and stick it right

00:06:49   into a UI in code or an interface builder, and it automatically will style itself not

00:06:54   only for that style, but it also will pick up things like in my OC appearance class,

00:06:58   I've defined default colors, default font attributes.

00:07:02   So for instance, in the San Francisco font, numbers by default are not proportional exactly.

00:07:09   Like a one is narrower than a zero, for instance.

00:07:13   They're not fixed proportions, rather.

00:07:17   In many of my contexts, I need that.

00:07:19   So I have one place to set that in the OC appearance manager, where I have a function

00:07:23   that's called something on the lines of default font attributes for text style.

00:07:27   And I know that in certain text styles, in almost all of them, I want my fixed width

00:07:31   numerals.

00:07:32   So I have that one place to set it.

00:07:34   And my OC styled label class can manage all that for me.

00:07:37   So all over the UI, I'm only having to change the stuff in one place.

00:07:41   I change one value in one OC appearance line, and then all the labels across my entire app

00:07:49   will automatically update.

00:07:51   Dynamic text is super easy, because all those styled labels, they include either a forced

00:07:57   fixed size for things that are really tight, like the labels that are in the title bar

00:08:00   on the now playing screen, or a dynamic size adjustment based on dynamic type.

00:08:06   So I can say, just create this label and have it be the regular preferred dynamic type size,

00:08:12   whatever the current size is.

00:08:13   Or I can have it say, that size plus two points, if something needs to be a little bit bigger,

00:08:18   minus two points, a little bit smaller.

00:08:20   And that makes it so easy to support these accessibility features, and to use dynamic

00:08:25   type, and make all that happen for people who want or need that, and still have this

00:08:29   incredible ease on the code side, where I don't have to code that into every view controller.

00:08:34   I don't have to have that part of every custom control.

00:08:38   It just automatically inherits from these few base classes I've made that manage their

00:08:41   own appearance, and then the OC appearance class that handles it all parametrically,

00:08:45   as you would say.

00:08:46   I have one place where I can change this.

00:08:49   If I want to change the font weight across the entire app, I change that in one place,

00:08:54   and one line of code in that class.

00:08:57   Doing it this way makes things so much easier.

00:09:00   And as conditions change, as styles change, as fashion changes in app design, or as Apple

00:09:06   adds things, like there's a rumor that they might soon add a system-wide dark mode, then

00:09:12   again, if you have designed this way, this gives you one place where you have to implement

00:09:16   that.

00:09:17   And then all the rest of your app automatically picks it up from your appearance manager.

00:09:22   You really should design this way if you can.

00:09:24   Yeah, and I think there's two levels of where this comes into play.

00:09:28   There's the side of it that you're talking about, where I think it's very much the following

00:09:34   the principle of not repeating yourself, of avoiding duplication, that you don't have

00:09:39   every single view controller has a viewDidLoad method that's just 50 lines of setting style

00:09:45   stuff.

00:09:46   And obviously a lot of this got better when they introduced the appearance manager stuff

00:09:49   to UIKit, which is certainly something that I think we both use.

00:09:53   But even beyond that, there's so much of this that you're still needing to have more things

00:09:59   than beyond that, and then even just other stuff beyond appearance, like the actual UIKit

00:10:05   appearance stuff that you actually need to do.

00:10:07   And so there's not repeating yourself and trying to consolidate all of this code into

00:10:12   a place that you can easily update.

00:10:16   What I like about that approach is you inevitably you'll have one-offs, and you'll have things

00:10:20   that are slightly different, but you can even inside of that you have two different methods

00:10:27   that are physically close to each other in your application that are doing the default

00:10:36   version and then there's the bold version or whatever it is.

00:10:39   By putting those logically close to each other, I find it so much easier when I'm debugging

00:10:44   when I'm like, I change one and I expect the other one to change, and it doesn't.

00:10:49   There's something even helpful about, well, all I have to do is look down a few lines

00:10:52   and I'll probably see where I'm doing it wrong.

00:10:55   But also I think it can be really helpful, even just at the really, really few all the

00:10:59   way down to the lowest level.

00:11:02   I run into this a lot, and I'm weird for doing my layouts this way, but I do a lot of my

00:11:07   view layouts programmatically.

00:11:10   So I do a lot of work in view will layout subviews and those types of methods.

00:11:15   That's just how I think, that's fine.

00:11:17   It's definitely not for everybody.

00:11:18   No, you don't have to apologize for that.

00:11:20   So basically a week after we did the episode about how I've been embracing Interface Builder

00:11:25   and Auto Layout, I converted to what you're doing.

00:11:29   Because I hit, just like everything with Interface Builder and Auto Layout, it's great until

00:11:34   you hit a wall.

00:11:35   And then you realize that you're spending an incredible amount of time and effort to

00:11:39   do things that you could really do very easily with a 10 line layout subviews function.

00:11:48   But in those layout subviews function, I think it's another place that I've found this kind

00:11:51   of parametric approach to be really, really powerful.

00:11:54   In some ways even more when you're early on especially.

00:11:59   If you define, I end up with a lot of these very, my view layout subviews methods are

00:12:05   often, it's half defining variables.

00:12:09   There's a lot of, I guess now that I'm in Swift, is all these let something equal something,

00:12:13   let something equal something.

00:12:14   That's like the first half.

00:12:16   And the second half is all the actual framework where I'm actually saying build the frame

00:12:20   and do the math and lay it out.

00:12:22   But you can do all these fun things where you're just like, okay, this is the padding,

00:12:25   this is the inside padding, this is the outside padding.

00:12:27   And you can put all those values as just values that you can change dynamically.

00:12:34   And it's so powerful when you're looking at a UI.

00:12:36   Because I feel like I can get the initial UI vaguely right, fairly quickly by eye.

00:12:46   But then there's a certain point that you're just kind of looking at and you're like,

00:12:51   that label just looks, I think there's a term for this where it's like visual centering,

00:12:58   is a lot of times you have something to do an icon design where something is technically

00:13:02   centered but it doesn't look centered because a perfect circle is easy to center.

00:13:09   But if say you have something that's really thin at the top and heavy on the bottom, it

00:13:12   can actually look like it's off center if it's actually centered.

00:13:16   And I think you have a lot of these things in user interface design where things can

00:13:21   be technically correct.

00:13:22   Like say you say, oh, I always have eight points of padding on the left side of all

00:13:27   my views.

00:13:28   But there's possible that somewhere in your layout, nine points would actually look better.

00:13:35   And so pulling all these things into these functions, so that there's no magic numbers

00:13:41   in your frame stuff, all your frame logic in this case is just equations.

00:13:47   And they're all nice labeled equations that are saying it's padding plus label width

00:13:52   plus padding or however you want to lay it out.

00:13:55   You're being very clear and explicit can make this really a powerful approach.

00:13:59   And I think it works both ways.

00:14:01   Either way, the last thing you want in your app is to have a design that is expressed

00:14:07   somewhere that you can't change easily.

00:14:11   I think even I remember to the extent of, I remember I think it was Vesper that I first

00:14:15   saw someone do this where they even were just in Vesper, I think they defined a bunch of

00:14:20   these things even in a plist file, which is an interesting approach they took.

00:14:25   Because it allowed non-developer people to make changes to the application's appearance

00:14:34   because they would just go into a plist and change stuff.

00:14:37   And so it's even more powerful in that sense of you can actually even extract all this

00:14:41   developer logic and put it into something that is a bit less scary.

00:14:45   You may not necessarily want your designer going into your code and changing things.

00:14:50   I mean, not against designers, they're lovely, but that's a problematic thing in a couple

00:14:55   of ways versus here's this plist file that you can change and it's much less likely to

00:15:01   cause problems or conflicts or issues down the road.

00:15:04   It's also, it lets them work faster.

00:15:08   It's part of when you're working on a team with multiple people like that, if you have

00:15:11   a separate designer, they can do their job faster if you can give them that kind of infrastructure

00:15:16   and that kind of setup.

00:15:18   And I think too, between our two main points, having these variables defined at the top of

00:15:25   your layout function versus me having them try to be defined in a central place, like

00:15:30   an appearance manager class, you can actually combine these things.

00:15:33   One of the principles of design generally is to not to have too many different things

00:15:38   in one layout.

00:15:40   So if you're gonna have certain fonts, don't have 10 different fonts in your app, have

00:15:45   maybe two or one.

00:15:49   Don't have regular, semi-bold, bold, heavy, and book, have two font weights and have one

00:15:57   boldish font weight and one regular font weight, things like that.

00:15:59   You try to minimize the amount of different combos you have because it just looks, it

00:16:04   tends to look better if you standardize on one or two values in each one of these areas.

00:16:10   Also one of the things you can do is you can define your default spacing between elements

00:16:16   on the screen, like default left margin, eight.

00:16:18   And you can have that in your appearance manager class.

00:16:21   And so you can have your custom layout functions, use that as a starting point.

00:16:26   And then for the ones that need additional padding, don't just put a match number in

00:16:30   that says nine, have it be default padding plus one.

00:16:35   Or even better, the floor of default padding plus 10%.

00:16:40   If it's proportional, it's even better 'cause then you can scale it to different sizes and

00:16:44   everything.

00:16:45   And so that kind of approach, it still allows you to standardize things and it's even better

00:16:51   for what you're describing as parametric design because then you can go to your appearance

00:16:55   manager class and even have spacing be one of those things that you can change in one

00:16:59   place and have the whole app change as a result.

00:17:02   Yeah, and it's so powerful when you get into this.

00:17:06   And I guess it's sort of why I wanted to do an episode on it.

00:17:09   It's something that I have, every now and then I'll go back, I mean, I have a lot of

00:17:12   old projects and some of them are still in the store.

00:17:14   And I'll go back and look at the code.

00:17:16   And of course, any programmer's worst nightmare is when you open something and there's just

00:17:23   all these magic numbers.

00:17:25   All these just, you know, and I call it, say, a magic number.

00:17:27   Just any number that doesn't have a label as to what it means is a magic number.

00:17:33   So sometimes you can get away with it if it's an obvious thing, like the number of times

00:17:38   I divide by 60, you know, and when I'm doing date or time things.

00:17:42   Like maybe that's okay.

00:17:43   It's not perfect.

00:17:44   No, you have a constant, seconds per minute.

00:17:46   There you go.

00:17:48   Sure, that's even better.

00:17:50   But what you're really doing is when you go into something and you have this font, it's

00:17:55   like, it's 18 here, it's 17 there, you don't know why.

00:17:59   Someplace you have padding here or you just have these numbers that are, it's like, you

00:18:03   know, I remember back in the day when I used to always assume that an iPhone's width was

00:18:08   320.

00:18:11   And you know, when the iPhone 6 came out, all of a sudden I had to go through my app

00:18:15   and I, you know, this is what I actually did.

00:18:18   I opened up Xcode and did, you know, search all for 320, for 640, for 480, like all of

00:18:26   these values.

00:18:27   And I found dozens of them everywhere.

00:18:30   And that's really problematic.

00:18:31   It's like, that really shouldn't be there.

00:18:33   That should be, in that case, it's proportional to the screen.

00:18:36   So somewhere I should have a, you know, device, get the device bounds, get the width, and

00:18:41   then it should just dynamically update.

00:18:44   And by making it not tied to something that's hard-coded in that way, it's like your example

00:18:49   with padding and using the floor rather than just adding one.

00:18:54   If you get out of those habits, like any time, in a weird way, you're doing something that's

00:18:58   so numerical, but it should have almost no numbers in it, that it's like, the numbers

00:19:02   only exist at the top, and then everything else is proportional and kind of expanding

00:19:06   from that.

00:19:07   It works really well.

00:19:08   Like I've been doing this a lot with, on my Apple Watch work, where, you know, there are

00:19:14   these two different sizes, and so you have to have a, but the weird thing with the watches,

00:19:19   you don't typically change the UI between the 48 and the 38, the 42 and the 38 millimeter

00:19:26   Apple Watches.

00:19:27   Like, it's not like you have a totally new, it's not like an iPad to an iPhone.

00:19:30   It's like, they're so close but slightly different.

00:19:33   And so everything you have to do has to be proportional.

00:19:35   Everything needs to be adaptable and flexible.

00:19:38   And then once you wrap your mind around it and kind of commit to that approach, it's

00:19:41   like all these things, just kind of like all these other problems that you would have otherwise

00:19:44   just kind of fall out.

00:19:46   We're sponsored this week by Linode.

00:19:48   Go to linode.com/radar and use code radar20 at checkout for $20 in credit.

00:19:55   Linode is a combination of high performance SSD Linux servers spread across eight data

00:19:59   centers around the world.

00:20:01   They're a fantastic solution for your server infrastructure needs.

00:20:04   You can get a server up and running at Linode in just under a minute, with plans starting

00:20:08   at just $10 a month.

00:20:09   That now gets you two gigs of RAM for just $10 a month.

00:20:12   This is like amazing pricing for what you get at Linode.

00:20:16   David and I are both customers of Linode.

00:20:18   We've both been there since long before they were sponsors of our show.

00:20:21   Linode's great.

00:20:22   I definitely recommend them.

00:20:24   Linode is, they have an amazing control panel.

00:20:26   They have amazing options.

00:20:27   They have amazing pricing.

00:20:29   This is great for things like if you have to run a server for your app or even if you

00:20:33   want to run a private Git server.

00:20:34   If you want to host databases, run a mail server, although you shouldn't run your own

00:20:38   mail server, but you can at Linode.

00:20:39   You can operate powerful applications.

00:20:41   I have, I think, I think Overcast runs on something like 16 Linode VPSs.

00:20:46   It's incredible.

00:20:47   You can do so much there from one little thing for 20 bucks a month all the way up, or for

00:20:53   10 bucks a month even, all the way up to me running Overcast there for something like

00:20:57   $1,000 a month with all these different servers, all these high specs.

00:21:00   You can do crazy stuff at Linode.

00:21:01   It's amazing.

00:21:02   I love it.

00:21:03   You should love it too.

00:21:04   Check it out.

00:21:05   Go to linode.com/radar.

00:21:06   He'll be supporting us by doing that, and you get $20 towards any Linode plan using

00:21:11   code RADAR20 at checkout, and they have a seven-day money-back guarantee, so there's

00:21:16   nothing to lose.

00:21:17   Thanks a lot to Linode for supporting the show.

00:21:20   So to finish out the show, it seemed also kind of a fun little thing for us to, now

00:21:23   that you've, hopefully at this point, we've convinced you that parametric design is a

00:21:27   good thing that you should at least build into your apps.

00:21:30   Once you've done that, there's some really fun things that you can use as a result to

00:21:34   make your apps better, and as an example, something that I do a lot when I'm trying

00:21:40   to kind of narrow in on a good design is I will have my app randomly change some of these

00:21:47   parameters inside of it, and it lets me experiment, or maybe not randomly even, but where it's

00:21:54   like I'm trying to work out what the right padding is, and so I set it to, you know,

00:21:59   it starts at one, and then five seconds later it goes to two, five seconds later it goes

00:22:02   to three.

00:22:03   So you can have your app grow and shrink and adjust as you go, because it's all just

00:22:10   numbers, and so if you build this approach, you can do stuff like that, where you can

00:22:16   kind of, I sometimes struggle to visualize in my head what different values are going

00:22:22   to be, and maybe that's part of why I'm not a designer, I'm a developer.

00:22:25   Like, I can't imagine it, I can just write it, but if you build your app this way, you

00:22:29   can sit there and be like, "I don't really know which one I should do."

00:22:33   Another example is you can take the same approach but with fonts, and you say--

00:22:37   >> It's like a random font.

00:22:39   >> Well, you only have so many system fonts, right?

00:22:41   And it isn't so much that you're trying to randomly pick a font, but it helps start

00:22:49   my mind thinking about how my app could be different if I try different things that I

00:22:54   wouldn't necessarily think to otherwise, that if I had to manually go through and type

00:23:00   in all the different font names, I would never do it.

00:23:02   But it's like you try through and you're like, "Huh, actually this one kind of looks

00:23:06   good.

00:23:07   Why does this one look good?"

00:23:09   And it may not be that I'm going to end up using that random font, but it's like,

00:23:12   "Huh, maybe the reason I liked that one," for example, is that it was more condensed

00:23:16   rather than more wide, or it had obviously big, obvious things like serifs or non-san

00:23:21   serifs or different font weights.

00:23:23   I feel like there's something to be said for just taking the approach of just having

00:23:28   your app be very flexible this way, and then taking advantage of the flexibility to be

00:23:32   like, "Let's change all the things."

00:23:34   And most of the time it's not going to look good, but every now and then you can kind

00:23:38   of look and be like, "That one.

00:23:41   That's the one that I like," and sort of dial into it.

00:23:44   And I think you did a similar thing when you were doing your dark mode, though for a different

00:23:49   reason, right?

00:23:50   Because you kept switching between the light and dark mode to accomplish, to make sure

00:23:54   that you were doing it right.

00:23:55   Yeah, it's actually kind of a way to make sure that you've accommodated for dynamic

00:23:59   changes on all of your screens.

00:24:01   I just set a timer in the app delegate to change color scheme every five seconds.

00:24:07   And I went through the entire—even if for some reason you find a way to change the color

00:24:12   scheme without being logged in, even the login screens change, the password reset screens

00:24:17   change, every screen in Overcast changes dynamically for dark mode, and any of the kind of theme

00:24:22   changes, dynamic text, everything, every screen changes.

00:24:26   Because I literally went through and had this running every five seconds where it would

00:24:29   toggle it, and I went through every single screen in the app and converted it.

00:24:33   And I actually—similar—I just made fun of you a second ago for random fonts, but

00:24:37   when I was picking Overcast's font back when I was developing 1.0, I did basically

00:24:42   that same thing.

00:24:44   I had a folder full of ten different custom fonts, plus a list of some of the built-in

00:24:49   ones, and I had all this dynamic appearance stuff already in place, mainly for this purpose.

00:24:55   And so I just tried it out, because you can't really do this in the simulator.

00:24:59   You really have to see on device.

00:25:01   You have to see how this stuff looks, whether it seems right, whether it fits in.

00:25:06   And so that's what I did.

00:25:09   I had the font be managed by this appearance manager class since 1.0, and I just tried

00:25:13   all these different fonts and different adjustments to the sizing and the line spacing and everything

00:25:18   else, and eventually found the one that I thought worked best and that I liked the look

00:25:23   of best.

00:25:24   But I think if there's an overriding theme of what we're getting at here, we as programmers,

00:25:31   we often are not the best designers.

00:25:34   I think it's safe to say.

00:25:37   Very safe.

00:25:39   And all the way back in episode number ten of this show, we called "Design by a Programmer,"

00:25:44   we talked about some of the ways we make images this way, and I would be horribly delightful

00:25:49   if I didn't mention Paint Code as being an incredible resource.

00:25:54   Paint Code not only allows you to draw stuff, and it's a vector drawing program that outputs

00:25:59   either images or source code, and you can render things dynamically, which is awesome

00:26:04   for parametric design.

00:26:05   But even within Paint Code, you can have variables in your Paint Code documents for things like

00:26:11   colors, stroke, widths, things like that, and you can dynamically just hit a button

00:26:17   like an up or down stepper control on some of these things to increase the stroke width

00:26:22   on everything in your document that uses it, or you can have colors that are derived from

00:26:26   other colors.

00:26:27   You can say this color should be base color minus 20% saturation, or whatever you want

00:26:31   to do.

00:26:32   You can have cool stuff like that in Paint Code.

00:26:34   I highly recommend this app.

00:26:36   It's amazing.

00:26:38   But this is all a way for programmers like us who are not really designers by training

00:26:44   or by skill, really, to fumble our way through.

00:26:49   And we discussed a lot back in episode 10 why you might want to do this yourself and

00:26:53   not hire a full-time designer, and for many people, that choice is made for them by economics.

00:26:59   So a lot of times, you are your own designer just because that's what you can afford

00:27:02   to do.

00:27:04   And it's nice when you have this kind of parametric approach because we don't inherently

00:27:10   -- we can't just, as you said earlier, we can't just kind of come up with the right

00:27:13   thing on our first try in our head.

00:27:15   We have to just kind of build it that way, try it, see it in the app, and then kind of

00:27:20   figure out, play with the values a little bit to see what really looks best, what really

00:27:24   works best here.

00:27:26   And when you have this kind of parametric approach, this kind of procedural value-based,

00:27:31   parametric centralized approach, it makes that so much more possible and so much easier

00:27:37   to be able to experiment with your design so that you can eventually come up with what's

00:27:40   right.

00:27:41   And I think in many ways, that is at the core of this idea is anything we can do as developers

00:27:47   to make experimentation and exploration of our app easier and safer.

00:27:54   I have complete confidence that if I may change one of these values, I'm not going to horribly

00:27:59   break everything.

00:28:00   And if I do, I just undo it.

00:28:02   It's not that kind of change where it feels heavy.

00:28:05   And anything we can do, I think, to make experimentation, to make exploration light and fun in some

00:28:12   ways, honestly, I think will allow us to make our apps better and to do it in a way that

00:28:19   fits a developer mindset.

00:28:21   And so anything you can think of, like this is an example where you take an approach to

00:28:25   your design that makes it fun and easy to experiment.

00:28:29   Maybe you can think of other places to do that in your application or in the way that

00:28:32   you build it.

00:28:33   But that kind of a freedom, I think, is what ultimately makes it so powerful and ultimately

00:28:37   I think allows individual developers or developers without big design budgets.

00:28:44   I can't come up with it right the first time, but if I take this approach, I can try a hundred

00:28:50   different designs in the time that a regular designer could only come up with one or two

00:28:56   just because I'm just iterating so quickly through it.

00:28:59   And I think that is at its core what makes this so powerful.

00:29:01   Exactly.

00:29:02   All right, best of luck everybody implementing your designing by programmer style here, designed

00:29:08   by math.

00:29:09   That's all the time we have for this week.

00:29:11   Thank you for listening everybody and we will talk to you next week.

00:29:13   Bye.

00:29:14   [BLANK_AUDIO]