What is the most important thing when we design and create our apps?
Colors, shapes, design, feature list, architecture, implementation, code quality and somewhere there a simple thought crosses your mind—how is the user going to interact with my app? Is it intuitive enough? Is it smooth enough?
As an iOS dev you know how important is to make your app pretty and resemble the real world in behavior, while also being intuitive and convenient.
Well, so do we. This is exactly why we are building our components in a way that allows both a great experience with the stock feature set and an option for easy customization, so you can fully realize your own ideas.
In this post, we’re going to mix together one of our components, a couple of natural laws and a good bit of imagination—and see what happens.
class
ViewController
:
UIViewController
{
let sideDrawerView =
TKSideDrawerView
()
let navItem =
UINavigationItem
()
override func
viewDidLoad
() {
super
.viewDidLoad
()
sideDrawerView
.frame
=
self
.view
.bounds
self
.view
.addSubview
(sideDrawerView)
self
.view
.backgroundColor
=
UIColor
.yellowColor
()
let navBar =
UINavigationBar
(frame:
CGRect
(x:
0
,
y
:
0
,
width
:
CGRectGetWidth
(sideDrawerView
.mainView
.bounds
),
height
:
44
))
navItem
.leftBarButtonItem
=
UIBarButtonItem
(title:
"CLICK"
,
style
:
UIBarButtonItemStyle
.Plain
,
target
:
self
,
action
:
"showSideDrawer"
)
navBar
.items
= [navItem];
navBar
.autoresizingMask
=
UIViewAutoresizing
.FlexibleWidth
sideDrawerView
.mainView
.addSubview
(navBar)
let sideDrawer = sideDrawerView
.sideDrawer
sideDrawer
.fill
=
TKSolidFill
(color:
UIColor
.grayColor
())
sideDrawer
.width
=
200
;
sideDrawer
.content
.backgroundColor
=
UIColor
.clearColor
()
var section = sideDrawer
.addSectionWithTitle
(
"Primary"
)
section
.addItemWithTitle
(
"Social"
)
section
.addItemWithTitle
(
"Promotions"
)
section = sideDrawer
.addSectionWithTitle
(
"Label"
)
section
.addItemWithTitle
(
"Important"
)
section
.addItemWithTitle
(
"Starred"
)
section
.addItemWithTitle
(
"Sent Mail"
)
section
.addItemWithTitle
(
"Drafts"
)
}
func
showSideDrawer
()
{
sideDrawerView
.sideDrawer
.show
()
}
}
class
PhysicsTransitionManager
: TKSideDrawerTransition {
var animator :
UIDynamicAnimator
!
var gravity :
UIGravityBehavior
!
var collision :
UICollisionBehavior
!
override
init
(sideDrawer: TKSideDrawer) {
super
.init
(sideDrawer: sideDrawer)
animator =
UIDynamicAnimator
(referenceView: (sideDrawer
.superview
)!)
gravity =
UIGravityBehavior
(items: [sideDrawer])
collision =
UICollisionBehavior
(items: [sideDrawer])
}
override
init
()
{
super
.init
()
}
override func
show
() {
}
override func
dismiss
() {
}
}
sideDrawer
.transitionManager
=
PhysicsTransitionManager
(sideDrawer: sideDrawer)
override func
show
() {
self
.transitionBegan
(
true
)
self
.sideDrawer
?
.frame
=
CGRect
(x: -
200
,
y
:
0
,
width
: (
self
.sideDrawer
?
.width
)!,
height
: (
self
.sideDrawer
?
.superview
?
.bounds
.height
)!)
self
.sideDrawer
?
.hidden
=
false
self
.animator
=
UIDynamicAnimator
(referenceView: (
self
.sideDrawer
?
.superview
)!)
gravity =
UIGravityBehavior
(items: [
self
.sideDrawer
!])
gravity
.gravityDirection
=
CGVector
(dx:
1
.0
,
dy
:
0
.0
)
animator
.addBehavior
(gravity)
}
collision
.addBoundaryWithIdentifier
(
"Bound"
,
fromPoint
:
CGPoint
(x:
200
,
y
:
0
),
toPoint
:
CGPoint
(x:
200
,
y
: (
self
.sideDrawer
?
.superview
?
.bounds
.height
)!))
animator
.addBehavior
(collision)
let itemBehavior =
UIDynamicItemBehavior
(items: [
self
.sideDrawer
!])
itemBehavior
.elasticity
=
0
.4
animator
.addBehavior
(itemBehavior)
self
.transitionEnded
(
true
);
override func
show
() {
self
.transitionBegan
(
true
)
self
.sideDrawer
?
.frame
=
CGRect
(x: -
200
,
y
:
0
,
width
: (
self
.sideDrawer
?
.width
)!,
height
: (
self
.sideDrawer
?
.superview
?
.bounds
.height
)!)
self
.sideDrawer
?
.hidden
=
false
self
.animator
=
UIDynamicAnimator
(referenceView: (
self
.sideDrawer
?
.superview
)!)
gravity =
UIGravityBehavior
(items: [
self
.sideDrawer
!])
gravity
.gravityDirection
=
CGVector
(dx:
1
.0
,
dy
:
0
.0
)
collision
.addBoundaryWithIdentifier
(
"Bound"
,
fromPoint
:
CGPoint
(x:
200
,
y
:
0
),
toPoint
:
CGPoint
(x:
200
,
y
: (
self
.sideDrawer
?
.superview
?
.bounds
.height
)!))
animator
.addBehavior
(collision)
animator
.addBehavior
(gravity)
let itemBehavior =
UIDynamicItemBehavior
(items: [
self
.sideDrawer
!])
itemBehavior
.elasticity
=
0
.4
animator
.addBehavior
(itemBehavior)
UIView
.animateWithDuration
(
0
.5
,
animations
: { () -> Void in
self
.sideDrawer
?
.hostview
?
.center
=
CGPoint
(x: (
self
.sideDrawer
?
.hostview
?
.center
.x
)! + (
self
.sideDrawer
?
.width
)!,
y
:(
self
.sideDrawer
?
.hostview
?
.center
.y
)! )
}) { (finished) -> Void in
self
.transitionEnded
(
true
)
}
}
override func
dismiss
() {
self
.transitionBegan
(
true
)
UIView
.animateWithDuration
(
0
.9
,
animations
: { () -> Void in
self
.sideDrawer
?
.hostview
?
.center
=
CGPoint
(x:
CGRectGetMidX
((
self
.sideDrawer
?
.hostview
?
.superview
?
.bounds
)!),
y
:
CGRectGetMidY
((
self
.sideDrawer
?
.hostview
?
.superview
?
.bounds
)!))
}) { (finished) -> Void in
self
.transitionEnded
(
false
)
}
gravity
.gravityDirection
=
CGVector
(dx: -
1
.0
,
dy
:
0
.0
)
collision
.removeAllBoundaries
()
collision
.addBoundaryWithIdentifier
(
"leftBound"
,
fromPoint
:
CGPoint
(x: -
250
,
y
:
0
),
toPoint
:
CGPoint
(x: -
250
,
y
: (
self
.sideDrawer
?
.superview
?
.bounds
.height
)!))
}
Of course, in order to run the project, you need UI for iOS. Get a free trial here.
Happy coding and... may the force be with you.
Sophia Lazarova is a Junior Developer in the Telerik iOS Team. She recently graduated from the Telerik Academy with flying colors to join the team and start adding value to the suite of the best iOS controls. She is passionate about software development in various technologies.