Chapter 22
Info Panel
A straightforward info panel with push controllers, popups and external links.
This chapter weaves the components we’ve created into a nice, unified app and user experience.
To recap, we have created the following things:
Now, to bring COSMOS to life, we need to address the following:
goTo
methodSo, let’s get to it.
Most of the work we’re going to be doing is centered around the WorkSpace
. Although we’ll have to tweak a couple of classes, it’s the WorkSpace’s setup()
where we will be creating objects and linking them together.
First, if you’ve been using the WorkSpace to launch or test any of the work you’ve been doing, now’s the time to clean it up and change the background color to COSMOSbkgd
.
It should look like this:
1
2
3
4
5
6
7
8
9
10
let COSMOSprpl = Color(red:0.565, green: 0.075, blue: 0.996, alpha: 1.0)
let COSMOSblue = Color(red: 0.094, green: 0.271, blue: 1.0, alpha: 1.0)
let COSMOSbkgd = Color(red: 0.078, green: 0.118, blue: 0.306, alpha: 1.0)
class WorkSpace: CanvasController {
override func setup() {
canvas.backgroundColor = COSMOSbkgd
}
}
Adding the stars background is dead-easy, just create a copy of Stars
and add it to the canvas, like this:
1
2
3
4
5
6
7
class WorkSpace: CanvasController {
let stars = Stars()
override func setup() {
canvas.backgroundColor = COSMOSbkgd
canvas.add(stars.canvas)
}
}
Done. Run it and you’ll be able to scroll through the COSMOS.
Adding the menu is pretty easy too. Just follow the same steps as above, and add the menu after you’ve added the background.
1
2
3
4
5
6
7
8
9
10
class WorkSpace: CanvasController {
let stars = Stars()
let menu = Menu()
override func setup() {
canvas.backgroundColor = COSMOSbkgd
canvas.add(stars.canvas)
menu.canvas.center = canvas.center
canvas.add(menu.canvas)
}
}
We want the behaviour of the menu to be like this: The menu should open only when the user presses on it, i.e. not anywhere else on the screen. This is why we make the canvas small (i.e. 80x80). Since the frame is this small the interaction with the menu’s canvas is limited only to this 80x80 view.
Simple.
This step’s a cinch. Create another variable for the info panel, then instantiate it in setup()
and add it to the WorkSpace’s canvas after you’ve added the menu.
Then, go into InfoPanel.swift
and add the following line to it’s setup()
:
1
self.canvas.opacity = 0.0
Since the opacity is
0.0
the canvas automatically will not receive touches, so adding it over top of the menu is okay at this point and will not prevent the user from touching the menu
Your WorkSpace should look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class WorkSpace: CanvasController {
let stars = Stars()
let menu = Menu()
let info = InfoPanel()
override func setup() {
canvas.backgroundColor = COSMOSbkgd
canvas.add(stars.canvas)
menu.canvas.center = canvas.center
canvas.add(menu.canvas)
canvas.add(info.canvas)
}
}
To connect the menu and background we’re going to use a nice little trick: we’ll add a special type of action to the menu and link that with the background’s goTo()
method.
Go into Menu.Swift
and at the very top of the file, above the class declaration, add the following line:
1
typealias SelectionAction = (selection: Int) -> Void
This is a type alias through which we’ll be able to assign a method from another class. The selection action is essentially the action to which we want to send the menu’s current selection.
Create a variable to hold reference to a selection action:
1
var selectionAction : SelectionAction?
Navigate down to createGesture()
and in the case .Cancelled:
block add the following:
1
2
3
if let sa = self.selectionAction where self.menuSelector.currentSelection >= 0 {
sa(selection: self.menuSelector.currentSelection)
}
Since we sometimes set the current selection to -1, we need the additional
where
statement
Remember this method from Chapter 14?:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func goto(selection: Int) {
let target = canvas.width * Double(gapBetweenSigns) * Double(selection)
let anim = ViewAnimation(duration: 3.0) { () -> Void in
self.bigStars.contentOffset = CGPoint(x: CGFloat(target),y: 0)
}
anim.curve = .EaseOut
anim.addCompletionObserver { () -> Void in
self.signLines.revealCurrentSignLines()
}
anim.animate()
signLines.currentIndex = selection
}
This method conforms to the same parameters as the SelectionAction
type alias we just created. It also takes an integer and figures out a target and animates to that point in its scrollview.
Finally, go to your project’s WorkSpace, and add the following line:
1
menu.selectionAction = stars.goto
Your WorkSpace should look like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class WorkSpace: CanvasController {
var background : ParallaxBackground?
var menu : Menu?
var info : InfoPanel?
override func setup() {
canvas.backgroundColor = COSMOSbkgd
background = ParallaxBackground()
canvas.add(background?.canvas)
menu = Menu()
menu?.canvas.center = canvas.center
canvas.add(menu?.canvas)
info = InfoPanel()
canvas.add(info?.canvas)
menu?.selectionAction = background?.goto
}
}
Run it and things should work like this for you:
The process for linking the menu and info panel is almost identical to the previous step.
In Menu.Swift
and at the very top of the file, above the class declaration, add the following line:
1
typealias InfoAction = () -> Void
Also, in Menu.swift
add the following class variable:
1
var infoAction : InfoAction?
Then, scroll down to the .Cancelled
section of the menu’s gesture and add the following condition:
1
2
3
4
5
6
7
8
if let ib = self.menuSelector.infoButton {
if ib.hitTest(center, from: self.canvas),
let ia = self.infoAction {
delay(0.75) {
ia()
}
}
}
Finally, go back to your project’s WorkSpace and add the following line:
1
menu.infoAction = info.show
Run it, and you should see this:
There are two files that should be included in your project. We’re going to play as soon as the application launches.
In the your project’s WorkSpace, create the following two class variables:
1
2
let audio1 = AudioPlayer("audio1.mp3")!
let audio2 = AudioPlayer("audio2.mp3")!
Then in setup()
, loop and play them like so:
1
2
3
4
5
audio1.loops = true
audio1.play()
audio2.loops = true
audio2.play()
Now things are sounding stellar.
We prefer the stars to start offset from any particular constellation. So, open Stars.swift
and add the following line to the end of setup()
:
1
bigStars.contentOffset = CGPointMake(view.frame.size.width * CGFloat(gapBetweenSigns / 2.0), 0)
If you haven’t already done so, now’s the time to update a couple of simple deployment settings.
Click on the COSMOS project at the top of the project navigator in Xcode. Then under the General tab, navigate down to the Deployment Info section. Choose the following settings:
AAAAAAAAND
WE.
ARE.
DONE.