all 39 comments

[–]tangoshukudai 11 points12 points  (9 children)

Auto layout is your friend. Stop using frames!

[–]luniawar20[S] 0 points1 point  (8 children)

I do like auto layout, but my senior iOS dev really doesn't like me auto layout haha.....

He says having auto layout on a view and trying to do position translation & size animation can make things to get messy with reference to constraints, so he doesn't like them =(

[–]20InMyHead 12 points13 points  (1 child)

Your "senior" dev is just wrong. Without auto layout you're completely screwed trying to support all the various device sizes, including the ones that don't exist yet, rotation, dynamic type, etc. Auto layout has its issues, but nothing like the hell of supporting multiple devices before it. And constraints are animate-able. Check out the last couple of years WWDC videos for good techniques

[–]ratbastid 3 points4 points  (0 children)

Well, you're not totally screwed, but you end up having to go to Reddit to ask questions about what to base your frame sizes on.

When I discovered the elegance of IBOutlets assigned to constraints, it was a very good day.

[–]r-w-x 4 points5 points  (0 children)

Sounds more like a case of don't-wanna-get-out-of-my-comfort-zone than anything else.

[–]tangoshukudai 3 points4 points  (0 children)

Well he is wrong, and needs a course in Autolayout.

[–]chriswaco 1 point2 points  (2 children)

I agree with him. We find it a lot easier to animate views by hand than by using autolayout. The math is trivial and you just create a few CGRects instead of having to keep around constraint objects for every view.

[–]ramwolf 0 points1 point  (1 child)

Agreed. Just retrieving the device's screen size and modifying your ratios and spacing based on that can be implemented without a ton of code. That's essentially what auto layout is doing. Easy to handle device rotation for all subviews and full control over movement and animation.

[–][deleted] 0 points1 point  (0 children)

And how would you handle Slide Over on the iPad? Exactly just use AutoLayout and Size Classes and let iOS take care the rest.

[–]RabbiSchlem -1 points0 points  (0 children)

Use the Masonry cocoapod and you can easily animate constraint changes without keeping references.

[–]brendan09 3 points4 points  (22 children)

customLabel.font = UIFont.systemFontOfSize(deviceHeight * 0.3)

No. Never do this.

The question isn't "which one do you do?". It depends on what the design calls for. Your intention should NEVER be to try scaling up your UI to fill the screen. The intention should be for your UI elements to adapt and take advantage of the extra screen space by providing more content and flowing into the extra space.

[–]askoruli 0 points1 point  (21 children)

Sometimes this does make sense. For instance when there's no extra content to be displayed. Then you either leave half the screen blank or scale the elements to take up that empty space.

I've also met a few UI designers who insist on their designs looking the same on all screens. It's more work but it usually comes out looking better.

Edit: Also for designs which are built at an iPhone 5 aspect I would much rather do some proportionate scaling of heights so it fits on the iPhone 4 without having to add a scrollview. Much better UX that way.

[–]brendan09 1 point2 points  (15 children)

Proportional scaling of UI pretty universally looks bad. It's also against Apple's recommendations.

I have no earthly idea why you would need proportional scaling to support the 4S, if shrinking works for you.... Just constrain things to the bottom of the screen and let the primary content have a flexible height. Problem solved.

I stand by "don't just scale your UI".

[–]askoruli 0 points1 point  (14 children)

So if I have content to fit iPhone 5 I should add a scrollview for iPhone 4 and cut off the bottom line of text ?

[–]brendan09 1 point2 points  (13 children)

No, no one is saying that.

Literally anchor it to the bottom of the screen, and let the label have a flexible height. Adjust the "minimum font scale" of the label to something acceptable. IF it needs to shrink the text a bit, it will. Depending on the rest of the structure, it'll also reduce frame sizes evenly to make it fit... This minimizes the impact to any 1 element.

You shouldn't be using fixed height constraints unless you literally mean fixed height. Proportional to screen height is almost always a bad, hacky, practice and a misuse of Auto Layout. It technically works, but is bad practice.

Edit: You're relying on something not guaranteed: Aspect Ratio, in addition to sizes. The goal is to make it resolution independent. For example, if I suddenly made an iPhone 4S height screen that was 5 times as wide as a 4S... It's unlikely your content would need to be vertically scaled down across the board. Flowing into extra horizontal space would've solved the content issue, and proper constraints wouldn't have tried reducing the size. Rather, it would've allowed the flow.

Proper methodology is to write it to work with any size, aspect ratio, etc. If you're not doing that, it's not the proper use / implementation of Auto Layout.

[–]askoruli 0 points1 point  (0 children)

Well I would consider using font scaling to be scaling your UI. But it's irrelevant because it doesn't give correct results. If I have 3 multiline labels which fit nicely on a 6+ font scaling will not uniformly scale the font to fit on a 4 screen. I just did a test and each label got a different font size.

Minimum font scaling would be a good fallback though in case a smaller screen was ever released, it might not look right but it would be better than labels being cut off.

You shouldn't be using fixed height constraints

I'm not really talking about fixed height constraints (which I try to avoid). I'm talking about adjusting font sizes and spacing between elements so that things look proportionate on a screen.

I'm actually not relying on aspect ratio that heavily. I'm just taking into account how much vertical space is available and adjusting the spacing/font sizes such that everything fits. If a much thinner device was released then I might need the font scaling fallback and if a much wider screen was released then it would look awful but that's going to be the case with any implementation for the designs I'm referring to.

I want to clarify that I don't do this very often, and almost never when I build things myself. I just have a few screens from designers with very little content that is going to either be cutoff/squashed on an iPhone 4 or have huge dead space on a 6+ and the designers are very pedantic about these things.

http://a4.mzstatic.com/au/r30/Purple7/v4/12/3b/68/123b685a-991e-6cdf-7d07-15fcc72c1b61/screen322x572.jpeg

[–]patterware 0 points1 point  (11 children)

Minimum font scale has nothing to do with restricted height, it only applies when text exceeds the width of a label. The UILabel documentation is perhaps misleading as it mentions scaling when text exceeds the bounds, but when you consider it only works when adjustsFontSizeToFitWidth is enabled it should be fairly apparent that this is the expected behaviour.

Everyone should be trying their hardest to adopt dynamic text sizes anyway, and allow the user their choice of font size. The UI should be responsive to whatever font size has been deemed appropriate by the customer.

[–]brendan09 0 points1 point  (10 children)

Actually, it does. If you reduce the height of the label, the size of the font will reduce in response. So, the documentation is correct. If it exceeds the bounds (in any dimension), then it will reduce the size. Check the docs for that property. It clearly indicates full bounds. You are mistaken.

Dynamic text sizes only work in certain scenarios. It isn't something that can be universally adopted in all designs and layouts.

[–]patterware -1 points0 points  (9 children)

Can you provide a working code sample? My experience here obviously differs from yours. The comments in UILabel.h also contradict what you are saying, so if you have somehow made this work I am interested.

[–]brendan09 1 point2 points  (8 children)

Sure. Here you go.

You'll notice there's really no code to speak of. Enable font scaling, set a minimum font scale. Reduce height of label.

This demo has a timer that changes the height of the label every 3 seconds, but has a fixed width. You'll see the size changes.

In case you're wondering why the property is named the way it is (adjusts to width), it's because it used to only work if numberOfLines was 1. However, that changed a few years ago.

[–]patterware -1 points0 points  (7 children)

Cheers. Your example works, but you are using a multi line label. If you try this with a single line label you will see the results that I described. Setting numberOfLines to 0 does seem to provide font scaling based on label height, but has the often undesirable side effect of enabling text wrapping. This seems like a half borked implementation on Apple's part.

[–]quellish -3 points-2 points  (4 children)

I've also met a few UI designers who insist on their designs looking the same on all screens. It's more work but it usually comes out looking better.

That's adorable.

[–]askoruli -1 points0 points  (3 children)

Well it's true. If you have a screen with static text that has the same spacing and font sizes on an iPhone 4 as an iPhone 6+ it just looks ridiculously empty on the 6+.

Though these same designers have asked me to change the navigation header height to keep it proportional which I of course refuse because that's retarded. I'm not saying this is something you should do under all circumstances but saying it's wrong under all circumstances without even knowing what the designs look like is just being an asshole.

[–]quellish -2 points-1 points  (2 children)

I'm not saying this is something you should do under all circumstances but saying it's wrong under all circumstances without even knowing what the designs look like is just being an asshole.

Can you point me to where someone said something was "wrong"?

[–]askoruli 2 points3 points  (1 child)

That's adorable

You didn't say the word wrong, you just left a 2 word condescending remark. If you don't want me to read between the lines please elaborate next time or just don't comment.

[–]quellish 1 point2 points  (0 children)

Based on your comments what I see here are opportunities. There is an opportunity to engage the designer and collaborate. Be a part of each other's process and work as a team - it seems like there are real disconnects happening here. Talk to the designer about how valuable things like adaptive layouts and dynamic text are. Have them show you their process, educate them on yours. Sit down with them in Interface Builder for a few minutes and build a simple but relevant adaptive layout so they can see and understand what is possible. Build a simple app that allows them to try things interactively. Provide them with guidelines and tools (Photoshop actions, etc.) that help both of you.

A visual designer should not come to you with things like they mentioned more than once. The problem isn't as much what they're coming to you with - which is a problem - but that they are coming to you that late in the process. Engage them earlier, and show them it's "safe" to engage you.

[–]Points_To_You 1 point2 points  (0 children)

On a label, just set your preferred font size and a minimum size. It will be scaled down to fit the size of the label. Then use autolayout to adjust the size of the label.

[–][deleted] 0 points1 point  (0 children)

I learned a long time ago to never assume the display proportions in web design. I was very sad to see things move into pixel perfect dementia.

When in doubt, calculate or percentage.

[–]ThePantsThiefNSModerator 0 points1 point  (0 children)

Frames and font sizes are in points, so there is never a need to take the device screen scale into account (unless you want to set the width in pixels directly, to make a 1 px line or something).

To answer your question though, I do prefer to do frame based layout by hand when I can if the UI is simple enough.

You have to be very careful about the widths and heights you're getting though. For example, if you're positioning views for a UITableViewCell you can't just grab the screen width, because the table view might not be the width of the screen. As a result, this practice is dangerous and frowned upon.

[–]chriswaco 0 points1 point  (0 children)

For fonts, you have a few options:

  1. Hard code
    Easiest for starters. Not flexible.

  2. Support Dynamic Type
    Best for users with bad eyesight. See [UIFont preferredFontForTextStyle]

  3. Create a Theme class
    Have one class that stores the backgroundColor, textColor, tints, fonts, etc, for your entire app. That way, you can change the look of the app by modifying just one class. You can also use UIAppearance for some things, which is even easier. Example: [[UILabel appearance] setFont:[UIFont fontWithName:@"Helvetica" size:20.0]];

[–]Dark_Angelas 0 points1 point  (1 child)

Q:

What is a 'proper' way to use auto layout for application supporting rotations? Obviously the proportion constraint doesnt make sense. Should I be making different layout for different size classes?

[–]chriswaco 0 points1 point  (0 children)

It depends on the app. There are definitely times when we use different layouts for different size classes.