DND 19: Designing for Smaller Dynamic Type Sizes

Design Notes Diary

Considering Small Dynamic Type Sizes

I have a pretty solid grasp about how to layout Pedometer++ for the larger Dynamic Type sizes. Generally I just follow the rule of making everything bigger, reflowing as appropriate for a great experience.

But what has gotten me thinking today is how to handle the smaller sizes.

When I’m adopting the larger sizes my design process is guided by a desire to increase the usability of the app for an audience with lower vision acuity. I’m not really sure what the guiding principle of the smaller sizes is.

Anecdotally I’ve seen folks choose these settings when they want to see more on the screen at once. It’s a preference rather than an enabling technology. That isn’t to say that I should ignore this expressed preference my user has made, but it does feel like treating it differently.

The very first recommendation for Typography in the HIG states:

Strive to maintain a minimum font size that most people can read easily.

Generally speaking larger things are more legible than smaller things. So ensuring that I don’t go too small seems important.

When I look at my stats for how widely used these smaller sizes are it looks like around 17.5% of users prefer a smaller size (compared to 11.5% who prefer a larger). So it is a pretty meaningful proportion.

Initial explorations

In most places I’m just letting the UI shrink down following Apple’s Dynamic Type guidelines. But one spot in particular that I’m struggling with is the main graph view.

At the default Dynamic Type size this is scaled to show a seven day view. When larger sizes the bars get wider showing fewer days at a time. If I follow this same pattern for smaller sizes then you end up with something like this:

Where the Medium size shows 8 days, the Small 9 days, and the Extra Small 10 days.

This certainly accomplishes the goal of expressing the user’s preference for more data but when I look at it I just really don’t like it. It starts to feel cramped and unwieldy. My instinct is to shrink the main large text labels, but to keep the bars at the default sizing…and essentially override the user’s expressed preference.

Request for Feedback

I’m still very uncertain about this, if you are a small Dynamic Type user and have thoughts on how you’d expect/prefer this UI to adjust for you I’d really love to hear it.

The best way to reach me is on Mastodon.

David Smith

DND 18: Creating Custom SF Symbols

Design Notes Diary

Custom SF Symbols

I’ve watch a few WWDC sessions and read the documentation about how to create custom SF Symbols, but I’ve never actually tried making them until today.

Previously, whenever I wanted to create a custom, variable size image asset I would typically use a tool like PaintCode to convert it into code and then use that code as an SwiftUI Shape.

This approach does work and will let me render variable size, pixel perfect image assets. However, it is really awkward and isn’t really how SwiftUI expects you to do it. As such, you miss out on things like text baseline alignment and automatic scaling with Dynamic Type.

So today I decided I should actually buckle down and try my hand at creating some custom SF Symbols. I need an symbol to represent a person in a wheelchair for the “Wheelchair Mode” in Pedometer++.

I followed this guide which adapted the instructions from Apple’s developer site to specifically what I needed to do in Sketch (my preferred vector editor right now).

The process is pretty straight forward:

  • Pick an existing Apple symbol that roughly matches the metrics of the symbol you are creating.
  • Select File > Export Template in SF Symbols
  • Open that file in Sketch
  • Replace the Symbols layers with your new symbol shapes
  • Export from Sketch as an SVG
  • Drag the resulting SVG into SF Symbols

Now you have a custom symbol in SF Symbols that you can adjust as desired. For example, I separated the wheels of this wheelchair. So that should I ever need to I can color them separately from the person’s outline.

Then I select File > Export Symbol, and boom, I have a custom SF Symbol (🎉).

Now instead of my old Shape based approach, I can refer to this symbol just like I would any systemNamed symbol.

And here it is in action (new on left, old on right)

In case you are curious. Here is a link to the SVG output of this process cfc-wheelchair.svg.

Now that I understand the process and know that it is super straightforward I’ve started to migrate all my custom glyphs into this format.

I can highly recommend this process, it was way simpler than I would ever have guessed it would be…and I’m no graphic designer.

David Smith

DND 17: Kind, Friendly Designs

Design Notes Diary

Small bits of kindness in Design

In yesterday’s design work, I had said that I built my switches with red and green as their default colors:

This was the obvious way to differentiate them and seemed like a reasonable way to go.

However, as I was thinking further about I realized this was actually not good at all. It is actually super mean and unkind.

What I’m subtly saying with this design choice is that good people increase their goal and bad people lower their goal. While that is probably a slight exaggeration, this is how my users would actually feel (at least subconsciously).

I don’t want to make apps that are unkind. I want apps that are encouraging and build up their users. I want to make apps that don’t make you feel bad about yourself.

So I have colored this bit of UI so that both sides of the stepper are green.

So if you are lowering your goal, that is awesome. Great job taking care of yourself. Set whatever goal best fits your current fitness goals. No judgement.

No More Switches

My old settings screen included a large number of UISwitch controls that the user would turn on and off.

I started to rebuild this screen just copying this design, and got pretty far in terms of making a UI that fits my new design language.

However, the more that I thought about it the less I liked using Switches. There is something about them that is inherently unfriendly. You are pressing a button without a clear explanation of what will happen. I can surround it with explanation text and hope to educate my users about what it means, but the reality is that this is entirely unnecessary.

Instead, what I should do is use a segmented control with clear labels about what the two states the user is choosing between are.

In this case, they are either operating with Rest Days enabled, or they are opting to require unbroken streaks. By labeling the choices clearly I am hopefully eliminating a bit of stress about changing this setting. I never want my users to be nervous about what a button is going to do before they press it.

Similarly, for the Wheelchair mode in Pedometer++ where I swap to counting pushes rather than steps. I can communicate much more clearly with a segmented control. Rather than “Wheelchair Mode On/Off”.

And again, for Merge Apple Watch data I can add inline explanation that if you loose if you change this setting, that you are going to see iPhone only data. This was implied in the previous explanation text, but now it is absolutely clear.

The more I thought about it today, the more I am convinced that UISwitches are a bad idea in most designs. They are hiding things from the user in a way that is slightly hostile. Opting for compactness in screen real estate, rather than clarity.

SwiftUI is amazing

I have finished rebuilding the Settings tab from UIKit to SwiftUI, and I gotta say SwiftUI is amazing. I had kept putting off this rebuild because I thought it would take at least two weeks to get done. These settings screens are some of the most complicated and intertwined bits of UI in the app.

Instead of taking two weeks, the rebuild took 1.5 days. I was blown away with how productive SwiftUI has made me.

Even more awesome than just the raw productivity is that these new views are way more accessible with Dynamic Type and VoiceOver. In UIKit it wasn’t hard to build support for them, but it did take effort. So many more things are just automatic in SwiftUI.

It certainly doesn’t hurt either that the resulting code is like 20% of the lines of code compared to the UIKit version.

Here is a quick overview of the working state of it, not final design, but all working in practice.

David Smith

DND 16: Building Custom Controls

Design Notes Diary


The Design Notes Diary has been a bit quiet recently. That isn’t because I’ve lost interest in it, rather that I’ve had a lot of trouble getting properly stuck back into work since the Holidays.

My current plan is to write a diary entry for every day in which I am doing ‘real work’, where I feel like I’m moving my apps forward. Sadly, I haven’t had many of those lately.

Instead I find myself recently seeking ways to appear productive, but not on the projects I should really be working on. The last few days this has been reviving my Podcast Searching project. Using the fantastic Whisper project, I can now generate “transcripts” at roughly 5x realtime right from my Mac.

I’ve gotten through all of Under the Radar, a good portion of The Talk Show, and Cortex so far.

Better Settings

Last Friday I was talking about how I needed to start being ruthless about limiting scope and wouldn’t be able to migrate the Settings Tab to SwiftUI as a result. Well that lasted less than a week.

I did some initial work to update the UI styling to match what I’ve been doing for the rest of the app and immediately found that trying to get a nice looking, Dynamic Type compatible UI in UIKit was going to be way more work than just overhauling it into SwiftUI.

So that is what I’m starting to do today.

Step Goal Stepper

First up was the Step Goal Stepper. Even this relatively simple control gave me some opportunity for creative design.

Firstly, I style the increment/decrement buttons with red & green:

Which I think looks pretty good. However, anytime you are doing design with red and green and intending the color to show differentiation you need to be careful of colorblindness concerns.

Thankfully, Pedometer++ already has a colorblind safe theme which users can select if they have difficulty distinguishing between red and green. So I make sure that I use their colors here as well.

The main reason I decided to re-write these controls was that I didn’t like how limiting UIKit felt for creating good Dynamic Type support. I wanted a UI that really grew to make use of the screen and providing clear, legible controls. This is the result with the largest Accessibility size selected.

Custom Controls

I’m trying to create a consistent design theme throughout the app. Something that is very round and “friendly”.

To that end I’ve been working on some custom controls for this settings panel, the built-in looks just don’t feel at home in this app.

The first one is a segmented control. I want a segmented control which I can style and adjust with Dynamic Type fluidly. I started off with this:

Which works but felt a bit heavy, so I opted for a rounded outline and an inset active marker. This also has the added benefit of making it dramatically clearer which element is selected:

From here I played around with adjusting the colors so that there is more contrast between the selected elements text and the background.

I think that works pretty well, I’ll now use it in practice for a while and see if it settles in nicely in use. Not convinced with the text colors yet but otherwise I’m liking it.

Stepper Control

I wanted to create a layout for the goal stepper that fit in better here too.

I tried a number of approaches with outline shapes and looks. But in the end I think a simple capsule shape works best.

Actual Productivity!

Neither of these designs are final but I feel great about making so much progress today. For the first time what feels like forever, I’m actually coding properly again and getting things done!

Feels good.

David Smith

DND 15: Ruthlessly Limiting Scope

Design Notes Diary

The Tyranny of the Churn Equation

Yesterday I spent the day building and analyzing the way subscription applications tend to grow and settle over time. I built a tool to estimate these values and wrote about it here.

Ruthlessly Limiting Scope

I’m reaching a point in the development of this Pedometer++ update where I need to starting drawing lines in the sand about what features are going to make it into v5.0 and which will have to wait.

I talked about this a bit on the last Under the Radar.

This means that I have to start being ruthless about scope. If I’m not, I know for sure that I will never get this out the door. I have a list of ideas and possibilities a mile long and if I’m not careful, I’ll look up and it will be June and I’ll still be working.

So after much consideration here is my list of features that are getting bumped to a future release.

Delayed for Now:

  • The Trends tab showing your step statistics over time
  • Any workout mode other than walking/hiking. No running, cycling or display of other workout types.
  • Rebuilding the Settings Tab in SwiftUI. I had hoped to get all the UIs into SwiftUI, but the Settings tab will have to wait. I’ll restyle it a bit to be in line with the new designs but under the hood it will remain UIKit for now.

This change also makes the marketing for this update more straightforward. The “story” for version five is now:

  • Support for iPhone based walk/hike tracking
    • Including support for the Dynamic Island and Live Activities
  • Support for Map based navigation during workouts
  • Improved Apple Watch workout tracking including support for the Action Button and Apple Watch Ultra
  • Visual redesign with robust support for Dynamic Type and VoiceOver

This is likely a much simpler story to tell and thus easier to market against. The update is about workouts and additional visual and accessibility improvements.

I feel pretty good about this todo list and where it leaves me for the next month or so. With this in mind my goal endpoint now is to reach a feature complete, “No More New Features” point by February 3rd. That’s three weeks from now and that feels manageable. I’d then spend most of February on polish, beta testing and marketing prep.

This kind of forward planning is helpful to me not because it has any relation to reality. I’ve been a software engineer long enough to know that you can’t reliably estimate how long things will take to build. Instead, I find that it is more a hedge against Parkinson’s Law (work expands to fill the time allocated). Especially since I’m self employed, If I don’t set deadlines for myself I will forever allow my work to expand until I never actually ship anything. Or as the axiom goes “Plans are worthless, but planning is everything”.

Brief excursion into using a custom Accessibility Font

I came across this post by Hilda Bastian regarding the Atkinson Hyperlegible font. This is a font designed for increased legibility, especially for low vision readers.

I had the thought to swap to it within Pedometer++ whenever the Accessibility Dynamic Type sizes are enabled to further increase the readability of the UI.

I did a bit of experimentation with it to see how big of an impact it would make. Again using my SwiftUI blur trick to get a sense of how the font performs in lower vision scenarios.

Here is my tab control in Atkinson:

Here it is in San Francisco Rounded:

To my eye, there was actually not a lot of a difference between the two in terms of readability. I tried it in a number of other UI locations and came to the same conclusion.

My initial analysis is that San Francisco is actually a super legible font already and so the marginal gain of this move would actually pretty small. This is not at all surprising as I know Apple has put a ton of effort into the legibility of San Francisco, but good to confirm empirically.

I realize not everyone’s eyes are the same as mine, and there might be a particular group where this would be a win, but to the best of my ability to determine San Francisco seems great.

I’m glad I check this out, but for now I’ll stick with San Francisco.

Better Week Summary View

One of the little design details that was annoying me about the layout of the main step graph view is that there was some dead space along the bottom of the graph when you scroll into the past. This was because at the bottom of the graph I show a little summary of your current week’s stats.

Given that I now dynamically scale the graph height as you scroll, I realized that I could now instead move the graph bar down when you scroll over to eliminate this issue. Here is the result:

Amusingly, while making this change, I had an issue where one of my spring animations was getting out of control and the the result was this kinda hilarious UI glitch:

David Smith