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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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: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:02
◼
►
All right, best of luck everybody implementing your designing by programmer style here, designed
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:14
◼
►
[BLANK_AUDIO]