Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

With Dynamic Type in iOS 7, how do I factor in more advanced layout issues, such as spacing between labels/views?

I'm updating my app to support Dynamic Type in iOS 7. It was relatively easy to make the text adjust its size depending on the system setting, but as I'm using it in the context of a UITableView and cells with multiple UILabels in them, text size isn't the only thing I have to worry about. If the text grows, the cell's height should as well, if the text shrinks, so should the cell height.

Also, if it gets smaller, it should obviously have less spacing between items when compared to at its largest size type (as at a small size the spaces between would be giant).

How do I change more advanced layout issues such as these when the user changes their Dynamic Type size?


Right now, I'm doing something really ugly that barely works. I look at the height of one of my labels and scale my constants with its size. But it's very imprecise, as, say 110% of a UILabel height at the current text size being used as the padding between elements will not necessarily be universally working.

So here's what I'm doing in that example:

    CGRect articleTitleRect = [article.title boundingRectWithSize:CGSizeMake(CGRectGetWidth(self.contentView.bounds) - 29, MAXFLOAT)
                                                          options:NSStringDrawingUsesFontLeading
                                                       attributes:@{ NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline] }
                                                          context:nil];
    self.urlConstant.constant = articleTitleRect.size.height / 5;
    self.previewConstant.constant = articleTitleRect.size.height / 5;

(Basically finding out what the height of a label is, then using percentages of that to infer the spacing. Again, very imprecise and doesn't work well universally.)

The other thing I considered doing was checking what the current preferredFontForTextStyle: is equal to at a point size, and for specific values hardcode the interface adjustments/spacing. This works a little better, but it still doesn't seem optimal to what Apple had in mind, as it's not terribly dynamic (it breaks if they add another type size, for example) and you're almost sniffing for values they don't give you off the bat (which makes it seem hacky).


So what do apps such as Tweetbot 3 (that now use Dynamic Type to set their UITableViewCell elements) do to make their UI look so well done over different Dynamic Type sizes? What's the best way to go about doing this? There honestly seems like no tutorials on the topic.

like image 262
Doug Smith Avatar asked Oct 31 '13 02:10

Doug Smith


1 Answers

This is something that you will have to do yourself, but iOS has given you the tools you need with TextKit. There is actually a lot of documentation in the Test Programming Guide.

For example, in the Working with Font Objects section, the UIContentSizeDidChangeNotification, which informs your app that the Dynamic Type value has changed, with a userInfo dictionary with the new value. This is the entry point to what changes you want to make. For example, if the new value is UIContentSizeCategoryAccessibilityMedium, the distance between two labels is 10 points, but if the new value is UIContentSizeCategoryAccessibilityLarge, you can set it to 15. Of course I'm just making up values, figuring out what works best is something you'll have to do through trial and error. However, once you figure out the right distances, making sure everything works shouldn't take more than a dozen lines of code.

Also take a look at UIFontDescriptor, especially the constants at the bottom of that reference. They let you access pretty much every font property and trait imaginable. You can use that to "build" your own font with custom properties. If you want to go that way, it's going to require a little bit more code, but TextKit provides you with a lot of different APIs when it comes to showing text on screen.

like image 118
Scott Berrevoets Avatar answered Dec 01 '22 12:12

Scott Berrevoets