Skip to content

Instantly share code, notes, and snippets.

@Tricertops
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Tricertops/28e36af0e500a4178f92 to your computer and use it in GitHub Desktop.
Save Tricertops/28e36af0e500a4178f92 to your computer and use it in GitHub Desktop.

Values with priority in KeepLayout

Every numeric value used in KeepLayout need to have associated priority. This pair is then passed to the underlying NSLayoutConstraint of Auto Layout.

Before

The KeepValue type was an ordinary struct with .value and .priority, so it had to be created using one of the provided functions:

view.keepWidth.equal = KeepRequired(100); // value 100, priority 1000

Every time you wanted to change the value, new struct had to be created:

view.keepWidth.equal = KeepHigh(80); // value 80, priority 750

There was also a proxy property .required that served as a shortcut to .equal = KeepRequired(x), since Required priority at Equal relation is used most often.

Now

The KeepValue type is not an ordinary struct and it’s now convertible from any scalar number!

Everywhere a KeepValue is expected, you can also use int or double. Such values don’t have an explicit priority, so Required is used:

view.keepWidth.equal = 100; // value 100, priority 1000

Feels like Swift? This is still Objective-C!

Did I remove the priority? No, you can still use existing functions:

view.keepWidth.equal = KeepHigh(80); // value 80, priority 750

But there are new macros that allows you to specify priority easily:

view.keepWidth.equal = 80 +keepHigh;

In contrast to (now deprecated) .required shortcut, this feature now works for .min and .max too:

view.keepWidth.max = 120;
view.keepWidth.equal = 100 +keepHigh;
view.keepWidth.min = 80;

Magic

So how does this work? This is not some compiler hacking around struct layout.

I’m using _Complex type of C99 that is used to work with Complex Numbers. Complex number is a pair of two real numbers and the imaginary part is used as the priority.

The advantage is, that these _Compled double values are convertible to plain double (imaginary part is lost) and more importantly, plain double is convertible to _Complex double (with imaginary part of zero). Since 0 is not a valid layout priority, handling of these cases is straightforward.

The last code example can be written as:

view.keepWidth.equal = 80 + 750i;

For better apps!
Martin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment