MondrianLayout alternatives and similar libraries
Based on the "Layout" category.
Alternatively, view MondrianLayout alternatives based on common mentions on social networks and blogs.
-
Masonry
Harness the power of AutoLayout NSLayoutConstraints with a simplified, chainable and expressive syntax. Supports iOS and OSX Auto Layout -
PureLayout
The ultimate API for iOS & OS X Auto Layout β impressively simple, immensely powerful. Objective-C and Swift compatible. -
MyLinearLayout
MyLayout is a powerful iOS UI framework implemented by Objective-C. It integrates the functions with Android Layout,iOS AutoLayout,SizeClass, HTML CSS float and flexbox and bootstrap. So you can use LinearLayout,RelativeLayout,FrameLayout,TableLayout,FlowLayout,FloatLayout,PathLayout,GridLayout,LayoutSizeClass to build your App θͺε¨εΈε± UIView UITableView UICollectionView RTL -
PinLayout
Fast Swift Views layouting without auto layout. No magic, pure code, full control and blazing fast. Concise syntax, intuitive, readable & chainable. [iOS/macOS/tvOS/CALayer] -
FlexLayout
FlexLayout adds a nice Swift interface to the highly optimized facebook/yoga flexbox implementation. Concise, intuitive & chainable syntax. -
Luminous
Luminous provides you a lot of information about the system and a lot of handy methods to quickly get useful data on the iOS platform. -
MisterFusion
MisterFusion is Swift DSL for AutoLayout. It is the extremely clear, but concise syntax, in addition, can be used in both Swift and Objective-C. Support Safe Area and Size Class. -
ManualLayout
β Easy to use and flexible library for manually laying out views and layers for iOS and tvOS. Supports AsyncDisplayKit. -
QuickLayout
Written in pure Swift, QuickLayout offers a simple and easy way to manage Auto Layout in code. -
Framezilla
DISCONTINUED. Elegant library that wraps working with frames with a nice chaining syntax. -
BBLocationManager
A Location Manager for easily implementing location services & geofencing in iOS. Ready for iOS 11.
InfluxDB - Purpose built for real-time analytics at any scale.
* Code Quality Rankings and insights are calculated and provided by Lumnify.
They vary from L1 to L5 with "L5" being the highest.
Do you think we are missing an alternative of MondrianLayout or a related project?
README
MondrianLayout - describing structured layout for AutoLayout
This image laid out by MondrianLayout
Layout code
HStackBlock(spacing: 2, alignment: .fill) {
VStackBlock(spacing: 2, alignment: .fill) {
UIView.mock(
backgroundColor: .mondrianRed,
preferredSize: .init(width: 28, height: 28)
)
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 50)
)
UIView.mock(
backgroundColor: .mondrianYellow,
preferredSize: .init(width: 28, height: 28)
)
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
HStackBlock(alignment: .fill) {
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
}
}
VStackBlock(spacing: 2, alignment: .fill) {
HStackBlock(spacing: 2, alignment: .fill) {
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
VStackBlock(spacing: 2, alignment: .fill) {
HStackBlock(spacing: 2, alignment: .fill) {
UIView.mock(
backgroundColor: .mondrianYellow,
preferredSize: .init(width: 28, height: 28)
)
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
}
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
}
}
HStackBlock(spacing: 2, alignment: .fill) {
VStackBlock(spacing: 2, alignment: .fill) {
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
UIView.mock(
backgroundColor: .mondrianBlue,
preferredSize: .init(width: 28, height: 28)
)
}
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
VStackBlock(spacing: 2, alignment: .fill) {
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
}
}
HStackBlock(spacing: 2, alignment: .fill) {
UIView.mock(
backgroundColor: .mondrianRed,
preferredSize: .init(width: 28, height: 28)
)
VStackBlock(spacing: 2, alignment: .fill) {
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
UIView.mock(
backgroundColor: .layeringColor,
preferredSize: .init(width: 28, height: 28)
)
}
}
}
}
.overlay(
UILabel.mockMultiline(text: "Mondrian Layout", textColor: .white)
.viewBlock
.padding(4)
.background(
UIView.mock(
backgroundColor: .layeringColor
)
.viewBlock
)
.relative(bottom: 8, right: 8)
)
Strucutured layout API and Classical layout API
- π Enables us to describe layout by DSL (like SwiftUI's layout).
- π Automatic adding subviews according to layout representation.
- π Supports integeration with system AutoLayout API.
- π Provides classical layout API that describing constraints each view.
Introduction
A DSL based layout builder with AutoLayout
AutoLayout is super powerful to describe the layout and how it changes according to the bounding box.
What if we get a more ergonomic interface to declare the constraints.
Structured layout API
Unstctured layout API (classic style)
Future direction
- Optimize the code - still verbose implementation because we're not sure if the API can be stable.
- Brushing up the DSL - to be stable in describing.
- Adding more modifiers for fine tuning in layout.
- Tuning up the stack block's behavior.
- Adding a way to setting constraints independently besides DSL
- AutoLayout is definitely powerful to describe the layout. We might need to set the constraints additionally since DSL can't describe every pattern of the layout.
Demo app
You can see many layout examples from the demo application.
https://user-images.githubusercontent.com/1888355/122651186-142e7d00-d172-11eb-8bde-f4432d0a0ac9.mp4
Overview
MondrianLayout enables us to describe layouts of subviews by DSL (powered by resultBuilders
)
It's like describing in SwiftUI, but this behavior differs a bit since laying out by AutoLayout system.
To describe layout, use buildSubviews
as entrypoint.
This method creates a set of NSLayoutConstraint, UILayoutGuide, and modifiers of UIView.
Finally, those apply. You don't need to call addSubview
. that goes automatically according to hierarchy from layout descriptions.
class MyView: UIView {
let nameLabel: UILabel
let detailLabel: UILabel
init() {
super.init(frame: .zero)
// Seting up constraints constraints, layoutGuides and adding subviews
mondrian.buildSubviews {
VStackBlock {
nameLabel
detailLabel
}
}
// Seting up constraints for the view itself.
mondrian.buildSelfSizing {
$0.width(200).maxHeight(...)... // can be method cain.
}
}
}
Examples
Sample code assumes run in UIView
. (self is UIView
)
You can replace it with UIViewController.view
.
Layout subviews inside safe-area
Attaching to top and bottom safe-area.
self.mondrian.buildSubviews {
LayoutContainer(attachedSafeAreaEdges: .vertical) {
VStackBlock {
...
}
}
}
Put a view snapping to edge
self.mondrian.buildSubviews {
ZStackBlock {
backgroundView.viewBlock.relative(0)
}
}
synonyms:
ZStackBlock(alignment: .attach(.all)) {
backgroundView
}
ZStackBlock {
backgroundView.viewBlock.alignSelf(.attach(.all))
}
Add constraints to view itself
self.mondrian.buildSelfSizing {
$0.width(...)
.height(...)
}
Stacking views on Z axis
relative(0)
fills to the edges of ZStackBlock
.
self.mondrian.buildSubviews {
ZStackBlock {
profileImageView.viewBlock.relative(0)
textOverlayView.viewBlock.relative(0)
}
}
Detail
Vertically and Horizontally Stack layout
VStackBlock
Alignment | center(default) | leading | trailing | fill | |---|---|---|---| |||||
HStackBlock
center(default) | top | bottom | fill |
---|---|---|---|
self.mondrian.buildSubviews {
VStackBlock(spacing: 4, alignment: alignment) {
UILabel.mockMultiline(text: "Hello", textColor: .white)
.viewBlock
.padding(8)
.background(UIView.mock(backgroundColor: .mondrianYellow))
UILabel.mockMultiline(text: "Mondrian", textColor: .white)
.viewBlock
.padding(8)
.background(UIView.mock(backgroundColor: .mondrianRed))
UILabel.mockMultiline(text: "Layout!", textColor: .white)
.viewBlock
.padding(8)
.background(UIView.mock(backgroundColor: .mondrianBlue))
}
}
Background modifier
label
.viewBlock // To enable view describes layout
.padding(8)
.background(backgroundView)
Overlay modifier
label
.viewBlock // To enable view describes layout
.padding(8)
.overlay(overlayView)
Relative modifier
.relative
modifier describes that the content attaches to specified edges with padding.
Not specified edges do not have constraints to the edge. so the sizing depends on intrinsic content size.
You might use this modifier to pin to edge as an overlay content.
ZStackBlock {
VStackBlock {
...
}
.relative(bottom: 8, right: 8)
}
Padding modifier
.padding
modifier is similar with .relative
but something different.
Different with that, Not specified edges pin to edge with 0 padding.
ZStackBlock {
VStackBlock {
...
}
.padding(.horizontal, 10) // other edges work with 0 padding.
}
ZStackBlock
Stacking views in Z axis (aligns in center)
ZStackBlock {
view1
view2
view3
}
Expands to specified edges each view
ZStackBlock(alignment: .attach(.all)) {
view1
view2
view3
}
Specifying alignment each view
ZStackBlock {
view1.viewBlock.alignSelf(.attach(.all))
view2.viewBlock.alignSelf(.attach([.top, .bottom]))
view3.viewBlock.alignSelf(.attach(.top))
}
Animations
// TODO: https://github.com/muukii/MondrianLayout/issues/19
Classic Layout API
Structured layout API(DSL) does not cover the all of use-cases.
Sometimes we still need a way to describe constraints for a complicated layout.
MondrianLayout provides it as well other AutoLayout libraries.
Activate constraints independently
view.mondrian.layout
.width(10)
.top(.toSuperview)
.right(.toSuperview)
.leading(.toSuperview)
.activate() // activate constraints and returns `ConstraintGroup`
Batch layout**
// returns `ConstraintGroup`
mondrianBatchLayout {
box1.mondrian.layout
.top(.toSuperview)
.left(.toSuperview)
.right(.to(box2).left)
.bottom(.toSuperview)
box2.mondrian.layout
.top(.toSuperview.top, .exact(10))
.right(.toSuperview)
.bottom(.toSuperview)
}
Examples
Attach in horizontally
view.layout.horizontal(.toSuperview, .exact(10))
Attach in vertically
view.layout.vertical(.toSuperview, .exact(10))
Edge attaches to other edge
view.layout.edge(.toSuperview)
view.layout.edge(.to(myLayoutGuide))
Installation
CocoaPods
pod "MondrianLayout"
SwiftPM
dependencies: [
.package(url: "https://github.com/muukii/MondrianLayout.git", exact: "<VERSION>")
]
LICENSE
MondrianLayout is released under the MIT license.
*Note that all licence references and agreements mentioned in the MondrianLayout README section above
are relevant to that project's source code only.