Awesome
<p align="center"> <a href="https://www.hackingwithswift.com/articles/9/best-alternatives-to-auto-layout"> <img src="https://www.hackingwithswift.com/uploads/recommended@2x.png" alt="Drawing" width="300px;" /> </a> </p> <p align="center"> <a href="https://www.hackingwithswift.com/articles/9/best-alternatives-to-auto-layout"> Winner of Hacking with Swift Recommended award </a> </p>You + Stevia = π¦
- π‘ Write concise, readable layouts
- π Reduce your maintenance time
- π¨ Compose your styles, CSS-like
- π΄ Plug Live reload and boost your iteration cycles
Reason - Example - Live Reload - Installation - Documentation
πΌ Visual Layout Api
layout {
100
|-email-| ~ 80
10%
|-password-forgot-| ~ 80
>=20
|login| ~ 80
0
}
β Chainable Api
email.top(100).left(8).right(8).width(200).height(44)
alignHorizontally(password, forgot)
image.fillContainer()
button.centerInContainer().size(50%)
equalWidths(email, password)
image.width(>=80)
π Equation-Based Api
email.Top == 100
password.CenterY == forgot.CenterY
login.Top >= password.Bottom + 20
login.Width == 75 % Width
(image.Height == 100).priority = UILayoutPriority(rawValue: 999)
All Generate native NSLayoutConstraints π
π¨βπ¬Try it!
Stevia is part of freshOS iOS toolset. Try it in an example App ! <a class="github-button" href="https://github.com/freshOS/StarterProject/archive/master.zip" data-icon="octicon-cloud-download" data-style="mega" aria-label="Download freshOS/StarterProject on GitHub">Download Starter Project</a>
π‘ Reason
Because nothing holds more truth than pure code π€
Xibs and storyboards are heavy, hard to maintain, hard to merge.
They split the view concept into 2 separate files making debugging a nightmare
There must be a better way
How
By creating a tool that makes Auto layout code finally readable by a human being.
By coupling it with live code injection such as injectionForXcode we can design views in real time
View layout becomes fun, concise, maintainable and dare I say, beautiful β€οΈ
Login View Example
In the project folder, you can find an example of a typical login view laid out in both native and Stevia for you to understand and compare the two approaches.
As a spoiler alert, the number of characters goes from 2380 to 1239 ( ~ divided by 2)
Write Half the code that is actually 10X more expressive and maintainable !
π΄ Live Reload
Live reload enables you to develop your views live without relaunching the app everytime.
Stevia + InjectionForXcode = #WhoNeedsReactNative?? π
<img src="http://g.recordit.co/i6kQfTMEpg.gif" height="300" width="360" />Just Cmd+S
and you can dev live in the simulator !
Learn more about how to set up live reload here.
βοΈ Installation
Stevia
is installed via the official Swift Package Manager.
Select Xcode
>File
> Swift Packages
>Add Package Dependency...
and add https://github.com/freshOS/Stevia
.
The Swift Package Manager (SPM) is now the official way to install stevia
. The other package managers are now deprecated as of 4.8.0
and won't be supported in future versions.
For Carthage/Cocoapods support (legacy versions) see documentation here.
π Documentation
The following will teach you the gist of Stevia in one minute.
To go further, you can refer to the full documentation here.
Stevia enables you to write readable Auto Layout code. It does so by tackling the 3 main components of layout: view hierarchy, layout and styling.
01 - View hierarchy
email.translatesAutoresizingMaskIntoConstraints = false
password.translatesAutoresizingMaskIntoConstraints = false
login.translatesAutoresizingMaskIntoConstraints = false
addSubview(email)
addSubview(password)
addSubview(login)
becomes
subviews {
email
password
login
}
02 - Layout
email.topAnchor.constraint(equalTo: topAnchor, constant: 100).isActive = true
email.leftAnchor.constraint(equalTo: leftAnchor, constant: 8).isActive = true
email.rightAnchor.constraint(equalTo: rightAnchor, constant: -8).isActive = true
email.heightAnchor.constraint(equalToConstant: 80).isActive = true
password.topAnchor.constraint(equalTo: email.bottomAnchor, constant: 8).isActive = true
password.leftAnchor.constraint(equalTo: leftAnchor, constant: 8).isActive = true
password.rightAnchor.constraint(equalTo: rightAnchor, constant: -8).isActive = true
password.heightAnchor.constraint(equalToConstant: 80).isActive = true
login.topAnchor.constraint(lessThanOrEqualTo: password.bottomAnchor, constant: 20).isActive = true
login.leftAnchor.constraint(equalTo: leftAnchor).isActive = true
login.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
login.heightAnchor.constraint(equalToConstant: 80).isActive = true
login.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0).isActive = true
becomes
layout {
100
|-email-| ~ 80
8
|-password-| ~ 80
>=20
|login| ~ 80
0
}
03 - Styling
email.borderStyle = .roundedRect
email.autocorrectionType = .no
email.keyboardType = .emailAddress
email.font = UIFont(name: "HelveticaNeue-Light", size: 26)
becomes
email.style { f in
f.borderStyle = .roundedRect
f.autocorrectionType = .no
f.keyboardType = .emailAddress
f.font = UIFont(name: "HelveticaNeue-Light", size: 26)
f.returnKeyType = .next
}
π¨βπ» Contributors
YannickDot, S4cha, Damien, Snowcraft, Mathieu-o, Blaz Merela, Theophane Rupin, Jason Liang, liberty4me, Scott Bates, Sai, Mike Gallagher, WaterNotWords, Mick MacCallum, Onur Genes
π₯ Backers
Like the project? Offer coffee or support us with a monthly donation and help us continue our activities :)
π² Apps using Stevia
Many top-notch Apps with millions of users use Stevia to write better Auto Layout code:
<img src="https://is4-ssl.mzstatic.com/image/thumb/Purple113/v4/4d/c1/70/4dc17011-3ca7-bf9a-5326-70db722686ca/AppIcon-0-0-1x_U007emarketing-0-0-0-6-0-0-85-220.png/230x0w.png" height="80px"/> <img src="https://is1-ssl.mzstatic.com/image/thumb/Purple113/v4/ac/38/7a/ac387a00-893c-66c4-8595-856ad9907c84/AppIcon-0-0-1x_U007emarketing-0-0-0-6-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/230x0w.png" height="80px"/> <img src="https://is2-ssl.mzstatic.com/image/thumb/Purple113/v4/60/90/af/6090afc0-f2b1-40e7-d74f-78fd4f7309eb/AppIcon-0-0-1x_U007emarketing-0-0-0-7-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/230x0w.png" height="80px"/> <img src="https://is2-ssl.mzstatic.com/image/thumb/Purple123/v4/30/0c/1c/300c1c5c-2ded-02bc-a073-14c2287509e4/AppIcon-0-1x_U007emarketing-0-0-85-220-0-7.png/230x0w.png" height="80px"/> <img src="https://is1-ssl.mzstatic.com/image/thumb/Purple113/v4/b5/a1/1d/b5a11d97-1982-6346-fab9-056ab6c55512/AppIcon-0-0-1x_U007emarketing-0-0-0-6-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/230x0w.png" height="80px"/> <img src="https://is5-ssl.mzstatic.com/image/thumb/Purple123/v4/8b/a0/64/8ba064be-c665-db32-9e63-5751c56dfb84/AppIcon-0-1x_U007emarketing-0-85-220-0-7.png/230x0w.png" height="80px"/> <img src="https://is5-ssl.mzstatic.com/image/thumb/Purple113/v4/94/ed/1c/94ed1cc6-dc70-9458-5ee1-f42d89d97e50/AppIcon-0-1x_U007emarketing-0-85-220-0-7.png/230x0w.png" height="80px"/> <img src="https://is5-ssl.mzstatic.com/image/thumb/Purple123/v4/76/bf/ab/76bfabcd-d607-b944-c7ce-433ffbbd09c0/AppIconFREE-0-0-1x_U007emarketing-0-0-0-5-0-0-sRGB-0-0-0-GLES2_U002c0-512MB-85-220-0-0.png/230x0w.png" height="80px"/> <img src="https://is5-ssl.mzstatic.com/image/thumb/Purple49/v4/dd/54/b5/dd54b556-b289-ce8f-4a21-d7d5fb688a69/pr_source.png/230x0w.png" height="80px"/>
- Mobike - The worldβs first and largest bike sharing system.
- Brightspace Pulse - Education app
- NerdWallet - Credit Score, Budget, Finance
- Yatra - Flights, Hotels & Cabs
- Yummypets - The world's cutest social network for pet lovers
- Invitation Maker - Greetings, Invite & Wishes
- Logo Maker - Create & Design 10,000+ Professional Logos
- Smart Cleaner - Delete Phone Photos, Contacts
- Tuner Eclipse - Free Guitar Tuner
- and many more...
You are using Stevia ? Please let me know @sachadso@gmail.com and I'll add you to the list π!
<a href="https://opencollective.com/freshos/backer/0/website" target="_blank"><img src="https://opencollective.com/freshos/backer/0/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/1/website" target="_blank"><img src="https://opencollective.com/freshos/backer/1/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/2/website" target="_blank"><img src="https://opencollective.com/freshos/backer/2/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/3/website" target="_blank"><img src="https://opencollective.com/freshos/backer/3/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/4/website" target="_blank"><img src="https://opencollective.com/freshos/backer/4/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/5/website" target="_blank"><img src="https://opencollective.com/freshos/backer/5/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/6/website" target="_blank"><img src="https://opencollective.com/freshos/backer/6/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/7/website" target="_blank"><img src="https://opencollective.com/freshos/backer/7/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/8/website" target="_blank"><img src="https://opencollective.com/freshos/backer/8/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/9/website" target="_blank"><img src="https://opencollective.com/freshos/backer/9/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/10/website" target="_blank"><img src="https://opencollective.com/freshos/backer/10/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/11/website" target="_blank"><img src="https://opencollective.com/freshos/backer/11/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/12/website" target="_blank"><img src="https://opencollective.com/freshos/backer/12/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/13/website" target="_blank"><img src="https://opencollective.com/freshos/backer/13/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/14/website" target="_blank"><img src="https://opencollective.com/freshos/backer/14/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/15/website" target="_blank"><img src="https://opencollective.com/freshos/backer/15/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/16/website" target="_blank"><img src="https://opencollective.com/freshos/backer/16/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/17/website" target="_blank"><img src="https://opencollective.com/freshos/backer/17/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/18/website" target="_blank"><img src="https://opencollective.com/freshos/backer/18/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/19/website" target="_blank"><img src="https://opencollective.com/freshos/backer/19/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/20/website" target="_blank"><img src="https://opencollective.com/freshos/backer/20/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/21/website" target="_blank"><img src="https://opencollective.com/freshos/backer/21/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/22/website" target="_blank"><img src="https://opencollective.com/freshos/backer/22/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/23/website" target="_blank"><img src="https://opencollective.com/freshos/backer/23/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/24/website" target="_blank"><img src="https://opencollective.com/freshos/backer/24/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/25/website" target="_blank"><img src="https://opencollective.com/freshos/backer/25/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/26/website" target="_blank"><img src="https://opencollective.com/freshos/backer/26/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/27/website" target="_blank"><img src="https://opencollective.com/freshos/backer/27/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/28/website" target="_blank"><img src="https://opencollective.com/freshos/backer/28/avatar.svg"></a> <a href="https://opencollective.com/freshos/backer/29/website" target="_blank"><img src="https://opencollective.com/freshos/backer/29/avatar.svg"></a>
π Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site :)
<a href="https://opencollective.com/freshos/sponsor/0/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/1/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/2/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/3/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/4/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/5/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/5/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/6/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/6/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/7/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/7/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/8/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/8/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/9/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/9/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/10/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/10/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/11/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/11/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/12/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/12/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/13/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/13/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/14/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/14/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/15/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/15/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/16/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/16/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/17/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/17/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/18/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/18/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/19/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/19/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/20/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/20/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/21/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/21/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/22/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/22/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/23/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/23/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/24/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/24/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/25/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/25/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/26/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/26/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/27/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/27/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/28/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/28/avatar.svg"></a> <a href="https://opencollective.com/freshos/sponsor/29/website" target="_blank"><img src="https://opencollective.com/freshos/sponsor/29/avatar.svg"></a>