In today's lab, we'll be creating a responsive UI for a simple drum pad app using AutoLayout.
To get started, first download the lab zip file or clone this repository onto your own computer:
git clone https://github.com/iosdecal/ios-decal-lab2
Open the file Drummer.xcodeproj
to start the lab.
Once you have opened the project in Xcode, notice the files present in the Navigator.
We have provided the following files for you to use.
Drumkit.swift
in theModel
folder - this file contains the "brains" of our app, including the filenames for the audio files that we'll be using, as well as a method for playing these audio files.DrummerViewController.swift
in theController
folder - this file contains the ViewController class that will connect our View created in Interface Builder to our Model. You will be adding code to this file in this lab.Main.storyboard
in theView
folder - this is where you will be creating your UI elements (buttons, labels, etc) and AutoLayout Constraints. This file is automatically created for you each time you start a new Xcode project.Assets.xcassets
in theView
folder - contains all of the images used in the app (we have only included app icon images, but if you'd like to add your own images to customize the app, add them here). This is another file that is automatically created for you each time you create a new Xcode project.Supporting Files
- contains all the audio clips we'll be using, as well as some other files we won't be using in today's lab (Ask a TA if you want to learn about them!)
Once you've become familiar with the files in our app, open Interface Builder (Main.storyboard
).
We have a total of 7 drum sounds, so we'll need to create 7 UI Buttons in our storyboard.
Once you open your storyboard file, drag one 'Button' out from the Object library
onto your empty View.
You can edit how the button looks by opening the Attributes Inspector
, which can be found in the Utilities sidebar to the right side of the screen. Feel free to customize the button as much as you want, but at minimum, change out the background color so that the buttons are easy to see.
Once you complete one button, create 6 others, and add them to your view in the following arrangement. Since we want each button to play a unique sound, give each button a unique integer tag from 0 to 6 (you can change a button's tag value using the Attributes Inspector
)
Try building your project now by pressing Command + R
or the "Run" button at the top left corner of Xcode. You'll see that the UI looks different than it does in the Interface builder, and that there is a lot of extra white space. You can rotate the simulator by pressing Hardware > Rotate
to reveal some more UI issues. To fix these problems, we will use AutoLayout!
For our app, we want to minimize the amount of whitespace by making the buttons as large as they possibly can be given the size of our screen. Instead of hard-coding in values for our buttons, we'll create constraints between each UI element.
To refresh your memory , you can create constraints in Storyboard by first clicking on a UI element, holding down Control
and then dragging your cursor to another UI element or view. To fine-tune your constraints, open the Size Inspector
in the Utilities
pane. Scroll downwards to view all constraints on your UI element.
You may add as many or as few constraints as you wish, but you must ensure the following to get credit for this lab:
- Every button should stretch in width and height to fill the entire screen (no hardcoded values for height and width!)
- All buttons must have the same height
- The first 6 buttons should have the same width and height
- The spacing (horizontal and vertical) between each button must be equal
- The label and the segmented control should remain the same height, regardless of screen size (Constrain their heights to a certain value).
Use the image below as a guide to make sure that you made your constraints correctly. Even though the screenshot only shows the UI for an iPhone 7, your app's UI elements should resize for any device size).
You are free to customize your UI however you'd like, as long as the constraint requirements listed above are satisfied.
Now that you've finished the UI, we can now connect our View to our Model. (Note: this portion of the lab is much shorter - you're almost done!)
Now we can start connecting the UI elements we created in our Storyboard to our ViewController file so we can edit them programmatically.
Open the Assistant Editor (pictured below) so that Main.storyboard
and DrummerViewController.swift
are both open.
"DrummerViewController" is the custom controller class associated with the view in Main.storyboard
. Usually, you will have to set each of your ViewController's custom classes in the Identity Inspector in Interface Builder on your own, but we have done this step for you.
Since we wan't our drum pad buttons to play an audio clip when pressed, we'll want to create an action in our ViewController that will be called each time the user taps a button.
To do this, highlight one of the buttons in your Storyboard, then Control + Drag from them into DrummerViewController.swift
. The Connection should be an Action, the sender type should be set to UIButton, and the function name should be set to "drumButtonWasPressed" (see image below).
Since we want all of our buttons to activate this method (not just this one button we control + dragged from), click the small icon next to your IBAction "drumButtonWasPressed", and drag from it to each of the other buttons to connect them (see image below).
To check that all your buttons were successfully connected to the IBAction, hover over the small circle next to "drumButtonWasPressed" in DrummerViewController.swift. All 7 buttons should appear highlighted in your Storyboard.
Now we have an action method that will be called any time a user taps one of the drum buttons. The first thing to notice here is that the sender
object being sent as an input to our function is of type Any
. In order to access the "tag" attribute of our UI Button, change sender
to have the type UIButton
. Now, you can access what tag attribute the button has by referencing sender.tag
.
As of now, nothing will happen. Since we want a drum sound to be played each time a user taps a button, we'll need to add some code to this action method.
@IBAction func drumButtonWasPressed(_ sender: UIButton) {
//TODO: play the drum sound corresponding to your button's tag
}
Once you've completed this step, each button should play a different sound clip. If all buttons play the same sound clip, make sure you set the "Tag" property for each button correctly in Part 2.
Once you've finished the lab, you can check-off with one of the course staff.
We will grade your work based off the following criteria (all requirements must be satisfied to receive credit).
- All buttons and UI elements must dynamically change as shown in the preview gif for any device size and orientation (use the image in part 3 as a guide for how your app should look).
- Tapping on a drum button must play a sound (your app needs to work!)