See the entire conversation

🎨 iOS Design and UX Tips 🎨 I’ll be extrapolating out things I’ve learned, read from the HIG and have seen that make an iOS app look and feel good. Tip 1) Make a table view row animate its selection state as it’s popping and pushing on the nav Stack.
45 replies and sub-replies as of Jul 20 2020

Tip 1 Continued: UITableViewControllers get this behavior for free. If you roll your own table view you’ll need to do it yourself. You can do so by grabbing the controller’s transition coordinator as seen in this (gasp!) Objective-C code here called in viewWillAppear 💫
💡Tip 2 💡 If you've got text whose primary function is long-form reading, make it easy to parse it by using the view's readableContentGuide.
💡 Tip 2 Cont. 💡 You can do this by constraining the text container’s width to the view’s readableContentGuide’s width. Or, on table view there is a property that will do much of the same thing to the cell’s contentView.
💡Tip 3 💡 Users expect Dynamic Type to be supported, and an app feels off if your text doesn't respond to their settings. While table or collection views coalesce this behavior for you in most cases, other times you'll need to use the UIContentSizeCategoryAdjusting protocol.
💡Tip 3 Continued💡 Luckily, most UIKit text controls adopt that protocol, so it's typically just a case of setting the protocol's only required boolean value to true. Plus, pairing these with stack views makes adapting to any text need a bit easier.
💡Tip 4💡 As mentioned above when designing for dynamic type, you'll often be dealing with UIStackView in these scenarios. In most cases, it makes sense to flip content from a horizontal to a vertical axis when accessibility content sizes are active.
💡Tip 4 Continued 💡 There are many ways to achieve this, but a very painless route is to leverage Combine and NotificationCenter's easy to use publishers. Just sprinkle in some operators, and then you've only got one line to manage things.
💡 Tip 5 💡 You want to utilize the margins guide of your superview with exceptions. Some developers are unaware of them, and fall into using magic numbers for padding. That should be the exception rather than the rule. Notice how the first label has no leading padding.
💡 Tip 6 Continued 💡 From a layout standpoint, you need to constrain your leading and trailing edges to the layout margins guide. Also, you likely want to avoid an explicit left and right anchor constraint for internationalization purposes.
💡Tip 7 💡 With many iOS devices using the home indicator these days, there are times when you want a rounded view to hug the edges near the top or bottom. For this, use the right rounded corner style. In this case, you want a continuous corner curve, *not* a circular one.
💡Tip 7 Continued 💡 This is hard to see in the image, but there are two views overlaid here. The top black one has the correct corner curve, and the bottom red view has the wrong one. You can see the outlines of the red view, they don't match the rounded corner of the device.
💡Tip 7 Continued 💡 Thankfully, this is just a "the more you know" situation. You can get a continious corner curve by setting the RoudnedCornerStyle property of a CALayer. The default is circular.
💡Tip 8 💡 SF Symbols have a lot of utility, and one advantage is they are easily made "adaptive". Continuing with accessibility sizes, you'll often want to make glyphs more prominent in these scenarios. Notice the right glyph is heavier matching the text, while the left isn't.
💡Tip 8 Continued💡 This is a matter of responding to the content size changes as we previously covered, and while it may depend largely on your code structure - I personally solve this using Combine as well.
💡Tip 9 💡 Responding to accessibility & device needs on the fly not only promotes user empathy - it also produces a more polished experience. One example? Using blur effects. Users may not want these if they have reduced transparency on, or the device is in low power mode.
💡Tip 9 Continued 💡 In the image above, imagine the device is in low power mode or reduced transparency is on. We forgo the blurred background & custom transition animation. Instead, we use an opaque background and a standard transition. Here's one way you can go about this:
💡 Tip 10 💡 When using context menus (or pull-down menus for UIButton) it's easy to throw a bunch of actions in them without proper grouping. Always logically group them by job (sharing, editing, etc.). Here, the menu on the left is harder to grasp than the one on the right.
💡 Tip 10 Continued 💡 *credit to @jsngr for the Twitter UI used above* API wise, this is trivial in SwiftUI - just provide a Divider(). In UIKit, you do this using a parent-child setup using a UIMenu with .displayInline as an option.
💡Tip 11 💡 Many users invert iOS' colors to help with light & color sensitivities. But, ensure you aren't degrading rich media in your app, which users likely expect to remain at their true fidelity. For images & media, you'll likely want them to forgo this setting.
💡Tip 11 Continued 💡 This requires almost zero effort to support - simply set accessibilityIgnoresInvertColors to false (which also will do the same thing for subviews of that view):
Wow, so many of these tips I’m making tickets for in our app to implement, thank you!👍🏽
I’ve actually wondered about this in the past. Great tip! Thanks.
My pleasure, love sharing stuff like this!
these small details is what I love in any App.
They are honestly the most fun to develop for too, I think. The best feedback is when I get an email when a user notices something like this.
These are incredibly helpful! Thank you for sharing!
Of course, happy to!
I switched to using this in my apps and it just looks so much better. It's a small change, but wow it makes an overall difference.
and if you want to support iOS 12 (and earlier) you use… 🤪 (Or implement it yourself, it’s really just a UIBezierPath mask that happens to have the nice continuous corners)
An App-Store-safe way to enable smooth continuous corners on UIView that works on iOS 11, 12 and 13. - lapfelix/UIView-SmoothCorners
For any iPhone X, XS, 11, 11Pro … I just use a view, anchored to the bottom with the radius set to 38.5 and it works like a charm.
But I’m pretty positive that your approach is the way to go; will consider some changes though.
So the alternative is an if-else to properly set the axis at the site of the stack view creation and then another if-else in the trait collection did change method, right?
Yup! If you’re already overriding it, it’s a good place to put in logic like this.
I’m loving how you’re doing this! Keep going 😻🙌
Combine in action. Very nice
Great tips! Thank you for the code snippets especially!
Pleasure is all mine, they’ve been fun to put together 😃
Great stuff in a great format Jordan!
Thanks Tobias, glad you like it, hoping to do more soon 😄
What are the differences? If I had to guess the first one allows you to scroll by dragging outside the readable area
Yes! An important distinction too
Fast and easy to implement! Thanks for the tip 🤗
Everything is in the details 👍
Indeed, it's the small things that make up the big ones :)