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]