iOS Kit was created to make prototyping for iOS fast and easy without compromising the quality or customization.
There are three core pieces that make up iOS Kit. There is the foundational elements that help iOS Kit mold to devices. There is the component library that’ll save you time by providing native iOS offerings, and then there’s the supporting functions that help power the foundation & components.
- Setup
Foundational Elements - Dynamic Layout
- Real device override
- Device details library
System Components - Action String Shortcuts
- Alert
- Banner
- Button
- Field
- Keyboard
- Navigation Bar
- Sheet
- Status Bar
- Tab
- Tab Bar
- Text
Supporting Functions
In Framer Studio, write –
ios = require 'iOSKit'
You can write any variable name you'd like, but for the purposes of this guide we'll be using ios
.
The most fundamental piece of this module is Dynamic Layout. Dynamic Layout is a robust layout engine that’ll not only help make positioning layers easier and smarter, it'll will make positioning layers across devices possible.
1pt = 1px * scale
Side note: you can also use the built-in functions.
ios.pt(6) #returns 3 points on iPhone 6 and 2 points on iPhone 6 plus
ios.px(1) #returns 2 pixels on iPhone 6 and 3 pixels on iPhone 6 plus
As we get away from using pixel positioning, we won't be using x & y based positioning. Instead, we'll be setting things called constraints. When you set a constraint, it's like saying that a layer can't go beyond a certain position. There are four constraints for positioning: leading, trailing, top, and bottom.
To set a leading & top constraint on a box, write this –
layer = new Layer layer.constraints = top:10 leading:10 ios.layout()
This will position the layer at x:20, y:20 on iPhone 6, and x:30, y:30 on iPhone 6 plus.
Side note: you can also do this on one line if you'd prefer using this syntax. Just replace the layer.constraints line from above with this line. You'll still need to run the ios.layout function.
layer.constraints = {top:10, leading:10}
If you set a leading & trailing or a top & bottom, Dynamic Layout will do its best to honor the constraints, which will mean the height/width will need to be adjusted. For example, if you set the constraints of a layer to leading: 0
and trailing:0
, the layer's width will be adjusted to the device's width.
WARNING - If you set too many opposing constraints, I'm not sure what'll happen. Best of luck. ¯\_(ツ)_/¯
Try to just set no more than one of each constraint.
One of the most powerful things of Dynamic Layout is relationships. Relationships allows you to link a layer onto another layer in a variety of ways.
When you declare a constraint, you can set a constraint as a layer instead of an integer. For example, if you have two layers (boxA & boxB) you can set boxB's top as boxA.
boxB.constraints = top:boxA ios.layout()
This will stack the boxes so that boxB's top edge is constrained to below boxA, but what if you want a little buffer? That's really easy. We'll use a little different syntax with wrapping the layer and buffer in brackets.
boxB.constraints = top:[boxA, 10] ios.layout()
This will set boxB's top edge to 10 points below boxA.
There are a couple other types of constraints that'll help make positioning layers even easier. There are two centering constraints: verticalCenter, horizontalCenter. These constraints will only accept just a layer as a constraint.
For example, if you'd like boxB to be horizontally centered on boxA, write this:
boxB.constraints = top:[boxA, 10] horizontalCenter:boxA ios.layout()
This will set boxB 10 points below boxA, and it'll center it within boxA on the x-axis. The other centering constraint verticalCenter will work simliarly center boxB within boxA on the y-axis. If you've set a top/bottom constraint, it'll ignore those constraints.
If you'd like to align boxB's trailing edge onto boxA's trailing edge, write this:
boxB.constraints = top:[boxA, 10] trailingEdges:boxA ios.layout()
- target (optional) Layer or Array of layers
When set, this will only animate the target layers with updated constraints. When this is not set, it'll animate all layers with their updated constraints. - curve, curveOptions, delay, repeat, colorModel String
Each of these properties will work the same as native animations - time Num
This will be the time of each layer's animation, not the entire animation of all the layers. - stagger Num
This will put an incremental delay across all layers being animated. - fadeOut Boolean or Layer
When set to true, this will animate all layers' opacity to 0. When set to a layer, that layer's opacity will be set to 0. - fadeIn Boolean or Layer
When set to true, this will animate all layers' opacity to 1. When set to a layer, that layer's opacity will be set to 1.
If we have a bunch of layers in a column and we want them to all move up, we can set the topLayer
's constraint to 50, and all the layers with a relationship with topLayer will also move up.
topLayer.constraints.top = 50 ##Set a new constraint ios.animateLayout stagger:.05 curve:"spring"
Note: When updating a constraint on a layer, please be careful on your syntax. Writing layer.constraints =
will wipe out your previous object.
This will wipe out your top constraint.
topLayer.constraints = top:50 leading:10 topLayer.constraints = leading:20
Where as, this will keep your top constraint.
topLayer.constraints = top:50 leading:10 topLayer.constraints.leading = 20
boxB.constraints = top:[boxA, 10] trailingEdges:boxA height:100 width:100 ios.layout()
#####When to call it
You'll need to call it before any x/y positions are referenced. If you have a function that's based off another layer, you'll need to call ios.layout before that positioning is stored otherwise it'll be wrong or 0. Once you call ios.layout(), it'll set the position to the accurate position.
#####Mixing up the queue
ios.layout will accept layers in the parathesis. This will layout only that layer and ignore all other constraints. This is to be used if a layer created after others needs to be laid out before others.
ios.layout(boxB)
This will only layout boxB and not boxA.
You may also want to play with the creation order if you're having issues with relationships.
For this to work properly, you'll need a full-screen browser. I use & recommend Frameless.
ios.scale # returns 1,2,3 ios.height # returns the height of the device in pixels ios.width # returns the width of the device in pixels ios.device # returns one of the device names below ipad # for any iPad other than the pro ipad-pro # for the iPad Pro iphone-5 # for iPhone 5, iPhone 5s, iPhone 5c, and iPhone SE iphone-6s # for iPhone 6 & 6s iphone-6s-plus # for iPhone 6 plus & 6s plus
Every component in this module was written to feel native to Framer, so the way you create components should feel as familar as creating a new layer. The difference is that in addition to Framer properties there's added customization parameters, which will be accepted, and any component that can accept constraints from Dynamic Layout is able to.
After creation, components will operate as native layers under the variable name you declared. The only difference is the sublayers of the component are accessible via dot notation, so it's easier for you to turn on event listeners etc.
-b
- bold string
-g
- make string green
-r
- make string red
-rb
- make string blue
-lb
- make string light blue
-o
- make string orange
-p
- make string pink
-y
- make string yellow
-#000000
- change color to any 6 digit hex code.
Alerts are blocking notifications that will force the users to address the alert before continuing.
- title String
Embolded text at the top. - message String
Body text before actions. - actions Array of Strings
Series of actions that can be taken on the alert.
alert = new ios.Alert title:"Warning" message:"Don't do this" actions:["OK", "Cancel"]
alert : { alert.modal alert.title alert.message alert.actions : { OK, Cancel } alert.overlay }
To listen to different actions, you can use dot notation if it's a single word or brackets for any case
- Dot notation
alert.actions.OK.on Events...
- Square bracket notation
alert.actions["OK"].on Events...
The banner is a non-blocking notification. Typically, the banner will send you to a specific screen in an app.
####Properties
- title String
Embolded top text - message String
Body text - time String
time string that appears next to title. - icon Layer
This will put the layer inside the banner and size it accordingly. By default, it's a green box. - duration Integer
This will override the time before the banner animates-out. By default, this is set to 7. - animated Boolean
When set totrue
sheet will animate-in.
**NOTE - ** The banner will be, by default, draggable. If you drag down, it'll reset, and if you drag up it'll dismiss & destroy the banner.
banner = new ios.Banner title:"Time to do something" message:"Don't miss out" icon:iconLayer animated:true
banner : { banner.icon banner.title banner.message }
To make the banner clickable, you can write -
banner.on Events...
Button is a small versatile component that handles press states automatically.
####Properties
- text String
Sets button text - buttonType String
Can betext
,big
,small
- style String
Can belight
,dark
, orcustom
- backgroundColor Hex Color
Will set the background on big buttons. - color Hex Color
Setssmall
andtext
colors. - fontSize Integer
When custom, sets the fontSize style property. - fontWeight Integer
When custom, sets the fontWeight style property. - blur Boolean
On big buttons, this will turn it slightly opaque and add background blur. - superLayer Layer
set the passed layer as the super layer. - constraints Constraints Object
will set constraints using Dynamic Layout.
button = new ios.Button text:"Download" buttonType:"small" color:"red"
####Schema
button: { button.label }
Listening to buttons is no different than normal framer.
button.on Events...
The field is a versatile input for the keyboard. Please note, this is not a HTML field.
####Properties
- text String
Adds text by default to the field. - placeholderText String
Sets the placeholder text. - placeholderColor Color String
Sets the placeholder text color. - borderRadius Integer
Sets border radius of field. - borderWidth Integer
Sets border width. - borderColor Color String
Sets border color. - color Color String
Sets text color. - backgroundColor Color String
Sets field background color. - width Integer
Sets width in points. - height Integer
Sets height in points. - constraints Constraints Object
Will set the field's constraints and run layout using Dynamic Layout - textConstraints Constraints Object
Will set the text's constraints and run layout using Dynamic Layout
####Example
field = new ios.Field placeholderText:"Enter a name or email address" constraints:{align:"center"}
####Schema
field: { field.placeholder field.text # after touchEnd event field.keyboard { ... Keyboard Schema } }
####Listening to keys inside of a field In order to listen for the return key or any other key, you'll need to wrap it up in a touch event since the keyboard only exists after the field is being touched.
field.on Events.TouchEnd, -> field.keyboard.keys.return.on Events...
The keyboard is a fully rendered component that mimics the native iOS keyboard. It'll adapt to all devices. (Not currently supported on iPad Pro)
####Properties
- returnText String
Overrides the text on the return button. - returnColor Hexcode String
Will set the return button color - animated Boolean
Will determine if the keyboard is animated in. By default, this is set to false.
board = new ios.Keyboard returnText = "Done"
board: { board.keysArray #contains all keys A-Z in array object board.keys { board.keys.a - board.keys.z board.keys.shift boards.keys.return boards.keys.num boards.keys.space boards.keys.emoji# if on iPad boards.keys.shift2 boards.keys.num2 boards.keys.dismiss }
}
You can listen to keys using dot notation or square bracket notation.
- Dot notation
board.keys.return.on Events...
- Square bracket notation
board.keys["return"].on Events...
##Sheet
The sheet is quick action list. The sheet component is super simple to create.
####Properties
- actions Array of strings
Series of actions that can be taken on the sheet. - animated Boolean
When set totrue
sheet will animate-in. - description String
When declared, a small grey text will appear at the top of the sheet. By default, this will not appear. - cancel String
This will override the label on the dismiss button.
**NOTE - ** The cancel button will always animate-out. You don't have to add any additional code to handle/animate that.
sheet = new ios.sheet actions:[“-r Delete, Edit, Share”] animated:true description:"Do something"
####Schema
sheet : { sheet.cancel sheet.overlay sheet.description sheet.actions : {"-r Delete", Edit, Share} }
To listen to different actions, you can use dot notation if it's a single word or brackets for any case
- Dot notation
sheet.actions.Share.on Events...
- Square bracket notation
sheet.actions["-r Delete"].on Events...
The status bar allows users to see the connection, current time, and battery.
####Properties
- carrier String
Carrier name ex. Verizon/Orange/FramerJS - network String
network strength ex. 3G/LTE. Only will be showed when a carrier is set. By default, this is set to the wifi icon. Upon setting carrier, this will be set to LTE. - battery Integer
Battery percentage - this will change the battery icon - signal Integer(0 - 5)
Changes number of filled/unfilled dots. Zero will set the singal to "No Network" - style String
Dark is black text. Light is white text. - clock24 Boolean
By default, it's set to false, so it's a 12 hour clock with AM/PM. When set to true, the clock will cycle through 0-23 hours and removes AM/PM.
statusBar = new ios.StatusBar carrier:"Verizon" network:"3G" battery:70 style:"light"
####Schema
statusBar : { statusBar.battery.percent statusBar.battery.icon statusBar.bluetooth statusBar.time statusBar.network statusBar.carrier statusBar.signal }