Skip to content
This repository was archived by the owner on Aug 3, 2024. It is now read-only.

Implementation of CAConstraint/CAConstraintLayoutManager for iOS that is compatible with equivalent OSX APIs.

License

Notifications You must be signed in to change notification settings

regexident/DLConstraintLayout

Repository files navigation

DLConstraintLayout No Maintenance Intended

Open Source, API compatible replacement of CAConstraint/CAConstraintLayoutManager for iOS.

While Core Animation CALayers on OS X support constraint-based layout handling, iOS lacks support for said technology, despite providing it for UIViews.

DLConstraintLayout aims to fill that gap by providing drop-in replacements for the missing CAConstraint/CAConstraintLayoutManager classes for iOS.

How to use it

Let's assume for a moment that you have a CALayer hierarchy that you want to layout using constraints.

On OS X you'd end up with layout code akin to this:

CALayer *layer = ...;****

layer.layoutManager = [CAConstraintLayoutManager layoutManager];

[layer addConstraint:[CAConstraint constraintWithAttribute:kCAConstraintMidY
											    relativeTo:@"superlayer"
                                                 attribute:kCAConstraintMidY]];

Alright, but how about iOS?

Well, all you'd need to do is this:

  1. Link your project against libDLConstraintLayout.a (while keeping this in mind.).
  2. Add -ObjC linker flag to project.
  3. If DLCL_USE_CPP_SOLVER is defined (see "ObjC vs. ObjC++" discussion below), add -lc++ linker flag to project.
  4. Add #import <DLConstraintLayout/DLConstraintLayout.h> to your layout controller's .m file.
  5. Copy & paste your code that's using OS X's CAConstraints into your iOS project and:
  6. Either: Replace all occurences of the CA prefix with DLCL… (and kCA… with kDLCL… respectively). (Regex substitution: s/(?<=\bk?)CA(?=Constraint)/DLCL/g)
  7. Or: Add -DDLCL_USE_NATIVE_CA_NAMESPACE to your project's Other C Flags and just use the code and prefixes as is. No changes necessary.

The code stays the same!

That's it.

(For more info see the included iOS/OSX demos.)

How it works

DLConstraintLayout makes this all possible by providing the classes DLCLConstraint and DLCLConstraintLayoutManager as 100% API compatible replacements for their OS X counterparts CAConstraint and CAConstraintLayoutManager respectively. It then utilizes @compatibility_alias and conditional #defines in order to allow you to address them the same way you'd do with CAConstraint and CAConstraintLayoutManager respectively.

iOS API safety

Before injecting its own layout logic into CALayer DLConstraintLayout will search for existing CAConstraint and CAConstraintLayoutManager classes and check them for API compatibility with their respective DLCL… counterparts.

Three scenarios are possible:

Scenario #1: No existing native classes found at runtime

If there simply exist no native CAConstraint(LayoutManager) classes, then DLConstraintLayout will just proceed to inject its logic into CALayer.

Scenario #2: Existing and API-compatible native classes found at runtime

If there however exist native CAConstraint(LayoutManager) classes and their APIs match those from their respective counterparts in DLConstraintLayout, then injection is aborted and the counterparts' +(id)alloc; methods instead switch to returning native instances instead. (Which is exactly what you witness when playing with the DLConstraintLayoutDemoOSX demo app, btw.)

Scenario #3: Existing but API-incompatible native classes found at runtime

Last but not least if there exist native CAConstraint(LayoutManager) classes and their APIs happen to mismatch (as one cannot foresee if Apple will design constrained CALayer layout on iOS the same as on OS X, if ever at all.), then DLConstraintLayout will throw a DLCLConstraintLayoutClassCollision exception in CALayer+DLConstraintLayout's +(void)load; method, terminating the app.

Objective-C vs. Objective-C++

DLConstraintLayout implements both a Objective-C, as well as a Objective-C++ flavoured layout solver. While both share the very same API and behaviour, benchmarks showed the Objective-C++ based solver to be (in some cases up to an order of magnitude) faster than the Objective-C one.

To enable the Objective-C++ implementation simply define DLCL_USE_CPP_SOLVER in the build settings of libDLConstraintLayout.a and add the -lc++ linker flag to the linking project.****

Demos

DLConstraintLayout contains an iOS demo target (DLConstraintLayoutDemo) as well as an OS X counterpart (DLConstraintLayoutDemoOSX) sharing the very same layout code (DLCLViewController.m).

ARC

DLConstraintLayout uses automatic reference counting (ARC).

Dependencies

None.

Creator

Vincent Esche (@regexident)

License

DLConstraintLayout is available under a modified BSD-3 clause license with the additional requirement of attribution. See the LICENSE file for more info.

About

Implementation of CAConstraint/CAConstraintLayoutManager for iOS that is compatible with equivalent OSX APIs.

Resources

License

Stars

Watchers

Forks

Packages

No packages published