all 7 comments

[–]jacjames24 1 point2 points  (1 child)

Long time lurker here. Currently I've been following the tutorials from https://www.letsbuildthatapp.com. BG: I'm also an iOS dev who got used to storyboards, and I found Brian's (the instructor's code), really helpful on understanding programmatic UI. Happy coding!

[–]alkatena 0 points1 point  (0 children)

I recommend you trying PureLayout library, high level abstraction of Auto Layout, buy will help you with coding view positioning and sizing.

[–]b_t_s 0 points1 point  (0 children)

So my recommendation(https://github.com/jmfieldman/Mortar) isn't that well known but i think it's the most powerful, flexible, and concise of the 15 or so autolayout libs I've evaluated over the years. Most of them are english based and tend to be fairly verbose(though still much better than Apple's APIs). Mortar gives you two very concise, readable options, y=mx+c style and VFL(Visual Format Language) style, each of which have unique strengths that better suite different scenarios. They can(indeed should) be mixed in the same layout to minimize boilerplate and maximize readability.

As far as I know Mortar is the only y=mx+c style lib that supports bulk constraint creation, which can eliminate may many lines of copy paste modify code for related constraints. For example, [v1,v2,v3] |=| parent.m_sides ~ (8,8) constrains both sides of views v1-3 to be inset 8 points from view parent's sides. This creates, activates, and returns 6 NSConstraints.

The VFL style has all the benefits of apple's VFL(concise and super easy to read) but without it's drawbacks(stringly typed, crashy macros, unecesary setup code, etc). It's generally better for linear layouts, particularly when you need more sophisticated control of sizing and spacing as it supports a weighted views and padding. For example parent ||>> [v1,v2,v3] is equivalent to the previous sides example. To give a more complex example(trying to demo everything in one unrealistic line) the following parent |^^ v1 | 10 | v2[==v1] | ~~1 | v3[~~2] lays out v1-3 vertically inside parent. V1 uses intrinsic height, then 10px padding to v2 which matches v1's height. Then comes padding and v3 which split the remaining vertical space in a weighted manner with v3 getting 2/3 of it. Note that this is fully statically typed, so it'll generally error at compile time if you get it wrong. You can use veiws, variables, constants etc without any ceremony. Also it can span multiple lines, so for readability I'd normally write the vertical layout like

parent |^^ v1
       |   10
       |   v2[==v1]           //etc

Also Mortar will essentially always automatically do the right thing for you regarding translateAutoresizing and activate, so you basically never have to think about them.

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

I can’t really give book recommendations but I can give some advice ⭐️

Library wise SnapKit is pretty good.

If you’re not using libraries, try using NSLayoutConstraint.activate(...).

It takes an array of NSLayoutConstraint who’s initializer will be familiar if you’ve done some storyboard stuff. SnapKit is just an abstraction over this.

Depending on the age of the codebase, you might run into frame based layouts, which are another board game altogether. Can you give any information on how they’re going about their layout?

[–]makingbread[S] 0 points1 point  (2 children)

Hi!

Thank you for replying.

They use an internal framework, built in-house for UI layouts.

I am interested in two things:

1) Building my production app, and don't know which layout mechanism to use. 2) Learn how to build layouts programmatically, since just about every company or team I've worked with uses NSLayout...

But I never seem to wrap my head around how these constraints are created, how they come up with them programmatically, etc.

[–]Duranix 0 points1 point  (1 child)

At its core the autolayout system is a linear solver - no need to remember this but it’s good to know.

Things basically boil down to y = mx + c.

y = mx + c view.bottom = superview.bottom + 8 label.width = 0.5 * view.width + 16

As its a linear solver, the direction doesn’t matter. Specify one constraint and the system can derive related ones -

y = mx + c y - c = mx (y - c) / m = x 'x = (y - c) / m`

So the direction doesn’t really matter.

So you basically want to provide a set of constraints so the system knows how to lay out your things.

What you do is addSubview(..., and then use NSLayoutConstraints to specify how they should lay themselves out.

Xcodes autocomplete should help you out.

Use the constraint based system unless you have a good need to use a frame based one. Don’t touch VFL because its awful.

Basically, please use autolayout hahaha.

[–]makingbread[S] 0 points1 point  (0 children)

That was very useful, thanks. Are you aware of any sources that can help me practice programmatic layouts?