Is there anything available in Xcode that allows for changing sizes(such as labels) for different languages? All I can find are mentions of using auto-layout to account for this but there are some areas where I have to change the label size. I could make an outlet for each label, detect the locale, and then change them that way but I was hoping for a cleaner solution.
The clean method is indeed auto layout, which can take the size of the text in a label into account. If that isn't good enough, then don't try looking at the locale, but look at the size of the text in the UILabel, measure it, and change things accordingly if needed.
Related
I wonder how we can fit different screen sizes with lots of textfields e.g. resize the fields/textsizes etc for Swift.
Here is my design at the moment:
https://ibb.co/wQF3rrQ
*Grey = textfields
I've tried with setting constraints and all of that, but it won't work. I can't find myself what's the problem.
Should I set the constraints programmatically rather than in StoryBoard?
There are multiple ways to do what you want.
Do you see the Vary For Traits button in your storyboard, located below your Xcode? There's a use for that. Take a look at Adaptive Constraints on Google, and you'll get tons of tutorials. Like this: https://medium.com/zendesk-engineering/ios-how-to-add-adaptive-constraints-to-support-a-universal-app-273663475b12
Second way is to make use of multiplier of your constraint.
Third way is the, uhmmm, a usual (or unusual) way of some developers I know. Make reference of each constraints, and toggle their values based on the screensize (or device) of the user.
In Xcode, when using the autoresizing option for any type of object, things seem to stay where they're supposed to be while maintaining a proportional size to the scene. I generally just select the inside arrows in the autoresizing box and everything maintains adequate sizes and proportions. However, I've seen multiple times on tutorials, blogs and videos that using constraints is "the right way". Why would the use of constraints be better than autoresizing when autoresizing seems to work perfectly? Would any problem surge when using autoresizing if I work only on iPhone in portrait mode?
Well there are a two reasons I think. The first is probably the most accurate, but might leave you feeling weird after. Because Apple is pushing it. Usually when apple is backing a new tool in their api, its wise to follow because they will drop support for old things you get used to like Autoresizing. Kinda sucks I know.
The second (better) reason that Autolayout will let you write view components that you can reuse between many different screen sizes. Yea Autoresizing helps, but Autolayout gives you more control when the screen size makes a large change like from iPhone to iPad. I've written views that live in all my iphone/ipad/apple tv apps.
An important reason is to allow views showing text, such as labels or buttons with titles, to adapt to the text content and font.
The text content should change due to internationalization/localization.
The font can change if Apple changes the system font or if the user asks for larger text to make reading easier.
With proper application of auto layout, your layout can adapt to such changes and still look good. Without auto layout, you would need to manually alter the layout to accommodate such changes.
If the text of a label in a universal storyboard is too long to fit some resolutions, how do I accommodate it?
Storyboard View
iPhone 6 Emulator
I'm not sure if there is a proper way to go about this according to the guidelines, but I would assume I would either text wrap onto multiple lines or adjust the font size automatically.
Here is a simple gif, which can help you to understand it better.
You can do either. First set the constraints so that the UILabel does not go past the edge of the screen. Then you have two options. Either set the minimum font size of set the number of lines to 0 (or both).
All of these settings can be set in storyboard.
Edit to following your comment
Constraints are usually set in the storyboard and dictate how a view is drawn based on the device you are using. It's a large and critical subject and Ray Wenderlich has a very good two part tutorial on it.
I have some ASCII syntax diagrams which must not have line breaks in the middle.
These don't have to be editable so I thought the best way is to use an UILabel with auto shrink option. But this option shrinks the text also if the content doesn't fit the height of the labels frame rectangle.
I just want to shrink only if the content doesn't fit the width. It would be absolutely fine to scroll vertically through the text.
What is the best way to do this with UILabel or any other UI element?
Use UITextView with 'editable' property set to false.
So let me rephrase your question. I guess what you want is a UILabel which can show multiple lines, but the longest line need to fit into the width of UILabel. If this is what you want, well the imagination is weird to me...
But anyway, I feel there's a conflict in your settings. First, allowing multiple lines implies you set "Lines" attribute (number of lines) as 0, which allows unlimited lines. But then Autoshrink will play no effect. I'm afraid it is not possible to be done by just setting the storyboard and instead, you need to write some code.
I guess people have raised related questions earlier, by which they want to dynamically change the font size when the text become too long. I guess you want to take a look about this:
Autoshrink on a UILabel with multiple lines
The last issue is you also want the scrolling effect (this is why I feel the outlooking will be weird.) But in short, to achieve this you need 1) dynamically change the UILabel height, most likely using the same technique as explained in the reference thread, and 2) wrap the UILabel in a scroll view. Maybe this can achieve what you want.
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.
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.
I haven't used dynamic type yet. But I think one approach you could use would be to use auto-layout to lay out your cell content, and let the auto-layouting engine determine your required cell heights. Then, when the dynamic type size updates you'd simply have to ask the tableview to either reload or recalculate (via beginUpdates/endUpdates).
I answered a question with an example of how to use auto layout to calculate the tableview cell height for any given cell, here:
How to resize superview to fit all subviews with autolayout?
EDIT
Per your comment:
Height's not really the issue here, I can calculate that rather
easily. My question is moreso how to deal with the harder things, like
space between labels for instance, where as the labels get bigger
their spacing should grow slightly as well. Also just basically
learning how best to adjusts layouts affected by Dynamic Type
Anytime you need to adjust a constraint at runtime once the constraint has been created and registered, you do so by adjusting the constant property of the constraint. So if you want to tweak the spacing between two items based on some other property (e.g. text size) you have to do that manually by adjusting the constraint constant that manages spacing for those two items. If the constraint was created in Interface Builder you need to bind it to an IBOutlet in somewhere so you can refer to 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 view. I don't think you can manipulate this in Interface Builder, but if you create your constraints in code you can. Using the multiplier you should be able to set up a spacing constraint that adjusts larger or smaller based on the height of some other element.
In a more complex scenario, you might desire to dramatically change the layout given some property change (e.g. text size), beyond tweaking simple spacing constraints. In this case I'd recommend either of the following:
1) Create and manage your constraints entirely in code. Tear-down and build up the correct set of constraints when you determine a layout changeover is required.
2) Create multiple nibs to manage multiple UI layouts via Interface Builder-defined constraints. Dynamically load/reload the correct nib when you determine a layout changeover is required. The possibly undesired side effect of this is all of your views/controls will be recreated.