With a dynamic type in iOS 7, how do I deal with more complex layout issues, for example between labels / views?

I’m updating my application to support dynamic type in iOS 7. It was pretty easy to make the text by adjusting its size depending on the system parameters, but since I use it in the context of UITableView and cells with several UILabels in them, the text size is not the only one what should i worry about. If the text grows, the cell height should also be if the text is compressed, therefore the cell height.

In addition, if it becomes smaller, it should have a smaller distance between the elements compared to its largest type (as with a small size, the gaps between them will be gigantic). A.

How to change more complex layout problems, for example, when a user changes his size of a dynamic type?


Right now, I'm doing something really ugly that barely works. I look at the height of one of my shortcuts and scale my constants with its size. But this is very inaccurate, because, say, 110% of the height of the UILabel with the current size of the text used as an addition between the elements will not necessarily work everywhere.

So here is what I am doing in this 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, figure out what the height of the label is, and then use the percentage of it to infer the interval. Again, it’s very inaccurate and doesn’t work well everywhere.)

Another thing that I considered was checking that the current preferredFontForTextStyle: is equal to the size of the point, and for specific values ​​- hard code for adjusting / spacing the interface. This works a little better, but it still does not seem optimal for what Apple had in mind, because it is not very dynamic (it breaks if they add a different type of size, for example), and you almost sniff for values, t give you right off the bat (which makes it seem hacked).


So what do apps like Tweetbot 3 (which now use Dynamic Type to set their UITableViewCell elements) do to make their user interface so well-executed for different types of dynamic type? What is the best way to do this? There honestly it seems that there are no textbooks on this topic.

+7
ios objective-c uitableview autolayout ios7
source share
2 answers

This is what you need to do yourself, but iOS has provided you with the tools necessary for TextKit. In fact, there is a lot of documentation in the Test Programming Guide documentation.

For example, in the Working with Font Objects section , UIContentSizeDidChangeNotification , which tells your application that the Dynamic Type value has been changed, using the 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 the two labels is 10 points, but if the new value is UIContentSizeCategoryAccessibilityLarge , you can set it to 15. Of course, I just compose the values, figuring out what works best is what you need make through trial version and error. However, as soon as you find out the correct distances, make sure that everything works, should not occupy more than a dozen lines of code.

Also see the UIFontDescriptor , especially the constants at the bottom of this link. They allow you to access all the properties and characteristics of fonts that you can imagine. You can use this to "create" your own font with custom properties. If you want to go this route, you need a bit more code, but TextKit provides you with many different APIs when it comes to displaying text on the screen.

+1
source share

I have not used a dynamic type yet. But I think one of the ways you could use would be to use auto-layout to place the contents of your cell, and let the auto-layout engine determine your desired cell heights. Then, when updating the size of a dynamic type, you just need to ask the table view to either reload or recount (via beginUpdates / endUpdates).

I answered a question with an example of using automatic layout to calculate the height of a tableview cell for any given cell, here:

How to resize a supervisor to fit all autostart subzones?

EDIT

For your comment:

Height is not quite a problem here, I can calculate that rather without difficulty. My question is how to deal with more difficult things, for example the space between labels, for example, when as the labels grow, their spacing should also slightly increase. It’s also easy to basically find out how best to set up layouts affected by the dynamic type.

Anytime you need to configure a constraint at run time, once a constraint has been created and registered, you do this by setting the constant property of the constraint. Therefore, if you want to adjust the spacing between two elements based on another property (for example, text size), you need to do this manually by setting a constraint constant that controls the spacing for these two elements. If a constraint was created in Interface Builder, you need to bind it to an IBOutlet somewhere so that you can reference it in code.

Constraints also have a multiplier property, which you can use to dynamically adjust one constraint based on the calculated attribute value of some other representation. I don’t think you can manipulate this in Interface Builder, but if you create your code constraints you can. Using the multiplier, you should be able to set a distance limit that will be adjusted more or less depending on the height of any other element.

In a more complex scenario, you may need to drastically change the layout when you change some properties (for example, text size), in addition to setting simple interval limits. In this case, I would recommend one of the following:

1) Create and manage your constraints completely in code. Dropping and creating the correct set of constraints when defining layout reconfiguration is required.

2) Create multiple tips to control multiple user interface layouts using the limitations of the Builder interface. Dynamically loading / reloading the correct tip when determining whether to switch layout is required. Perhaps the undesirable side effect of this is that all of your views / controls will be recreated.

0
source share

All Articles