1-click AWS Deployment 1-click Azure Deployment
Overview
UIkit is modern CSS framework. It is lightweight and modular framework for developing fast and powerful web applications. It is very simple to use the UIkit, You can easily customize and extend the features.
A UI kit is a set of files that contains critical UI components like fonts, layered design files, icons, documentation, and HTML/CSS files. UI kits can be fairly simple with a few buttons and design components, or extremely robust with toggles that change fonts, colors, and shapes on the fly.
UI kits save you time and keep you consistent by allowing you to create, edit, or expand on the existing components without creating them from scratch. Things like checkboxes, arrows, drop-downs, and forms are not worth re-inventing, especially when prototyping.
UIkit provides rich layouts components, responsive design, animations and transitions. UIkit gives you nice collection of HTML, CSS and JS components which you can easily use and customize.
- Responsive– It is developed with the mobile-first approach. It is fully responsive across all devices.
- Customization– UIkit can be easily customized as per the your theme.
- Components– It provides ready made beautiful components with clear naming convention.
- LESS– It uses SASS and LESS to write the well-structured which can be easily extended.
- Open Source– It is open source which you can use free of cost.
What Is the UIKit Framework:
While the Foundation framework defines classes, protocols, and functions for both iOS and OS X development, the UIKit framework is exclusively geared towards iOS development. It’s the equivalent of the Application Kit or AppKit framework for OS X development.Like Foundation, UIKit defines classes, protocols, functions, data types, and constants. It also adds additional functionality to various Foundation classes, such as NSObject
, NSString
, and NSValue
through the use of Objective-C categories.Objective-C categories are a convenient way to add extra methods to existing classes without the need for subclassing.
Instead of exploring the key classes of UIKit, like we did for the Foundation framework, we’re going to create and journey through a new iOS project, exploring the classes we encounter. By taking this approach, it will quickly become clear in what context a class is used, how each class fits into the broader scheme of an iOS application, and what role it plays.
UI kits, or user interface kits, help you improve your design workflow. They also encourage recycling components instead of creating new ones from scratch. They’re commonly used for mobile design or prototyping, largely because two of the biggest operating systems—iOS and Android—both have robust, well documented, and heavily supported design systems. (Note that design systems and UI kits often go hand-in-hand. A design system relates to both the code components and UI design, while a UI kit refers to the designer’s version of the design system. A UI kit can stand alone without any relation to a larger design system.)
UIkit Installation Steps :
There are following ways to install UIkit Installation-
Using NPM
Run the following NPM command to install UIkit-
Install UIkit Using NPM Command Example:
npm install uikit |
Using Hosted CDN
You can use hosted CDN to install the UIkit css. You can include the UIkit JS and CSS from CDN url simply as below-
Install UIkit CDN URL:
<!-- UIkit CSS --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.35/css/uikit.min.css" /> <!-- UIkit JS --> <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.35/js/uikit.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.35/js/uikit-icons.min.js"></script> |
Install Locally
You can download the CSS and JS from Download UIkit and include the CSS and JS files.
Clone From Git Repo
You can clone the files from Git repository.
Install UIkit Git Command:
git clone git://github.com/uikit/uikit.git |
UIkit Container:
UIkit Container– This component allows you to create container which is center aligned. Class .uk-container is used to create simple container. Here in this tutorial, we are going to explain how to use container component. You can also use our online editor to edit and run the code online.
UIkit Container Example
To create container add class uk-container, It will contain the max-width of the website with padding on both sides.
UIkit Container Example:
<div class="uk-container"> <h1>Learn UIkit on Tutorialsplane.com!</h1> </div> |
UIkit Section:
UIkit Section– UIkit provides css classes to create horizontal layout sections with different styles. It is very simple to create sections in UIkit.
UIkit Section Example
Sections are basically used to separate the page in different-different blocks. To create a section you just need to add class .uk-section. Here is simple example of section.
By default sections are blank so we need to add class .uk-section-muted. Let us create a simple container.
UIkit Sections Example:
<div class="uk-section"> <div class="uk-container"> <h3>My section</h3> </div> </div> |
Style Modifiers
You can add following modifiers to change the style of modifiers.
- .uk-section-default– This class will add the background color to the section.
- .uk-section-muted– This adds the muted background color.
- .uk-section-primary– This adds primary background color.
- .uk-section-secondary– This adds secondary background color.
Example
Modifier Example:
<div class="uk-section uk-section-primary"> <div class="uk-container"><h1>Primary Section..</h1></div> </div> |
UIkit Grid:
UIkit Grid UIkit provides classes to create responsive, fluid and nested grid container. Here in this tutorial, we are going to explain how to create grid containers in UIkit. You can also use our online editor to edit and run the code online.
UIkit Grid Example
To create grid container, add attribute .uk-grid to div and add child div. You don’t need to add class to create class. Let us create a simple grid.
UIkit Grid Example:
<div uk-grid> <div>Column 1</div> <div>Column 2</div> <div>Column 3</div> </div> |
If you run the above example it will produce the following output-
Gutter Modifiers
- .uk-grid-small – Add this class to apply a small gutter.
- .uk-grid-medium– Add this class to apply a medium gutter like the default one, but without a breakpoint.
- .uk-grid-large– Add this class to apply a large gutter with breakpoints.
- .uk-grid-collapse– Add this class to remove the grid gutter entirely.
Example
Gutter Modifier Example:
<div class="uk-grid-small uk-child-width-expand@s uk-text-center" uk-grid> <div> <div class="uk-card uk-card-default uk-card-body">Item</div> </div> <div> <div class="uk-card uk-card-default uk-card-body">Item</div> </div> <div> <div class="uk-card uk-card-default uk-card-body">Item</div> </div> </div> |
Divider Modifier
Add .uk-grid-divider class to separate the grid cells.
Divider Modifier Example:
<div class="uk-grid-divider uk-child-width-expand@s" uk-grid> <div>Dummy Text., Dummy TextDummy TextDummy TextDummy TextDummy TextDummy TextDummy Text</div> <div>Dummy Text Dummy Text Dummy Text Dummy Text Dummy Text Dummy Text Dummy Text Dummy Text.</div> <div>Dummy TextDummy TextDummy TextDummy TextDummy TextDummy TextDummy TextDummy TextDummy Text.</div> </div> |
Match Height
Add class .uk-grid-match to make each cell height same.
Make Grid Cell Height Same Example:
<div class="uk-grid-match uk-child-width-expand@s uk-text-center" uk-grid> <div> <div class="uk-card uk-card-default uk-card-body">Item</div> </div> <div> <div class="uk-card uk-card-default uk-card-body">Item<br></div> </div> <div> <div class="uk-card uk-card-default uk-card-body">Item Line 1<br>Line 2<br>Line 3</div> </div> </div> |
If you run the above example it will produce the output something like this-
Match Only One Cell
Add class .uk-grid-item-match to the grid whose child you want to make same.
<div uk-grid> <div class="uk-grid-item-match"></div> <div></div> </div>
Grid And Width
You can use width component to add the width of UIkit grid. Here is an example-
<div uk-grid> <div class="uk-width-auto@m"></div> <div class="uk-width-1-3@m"></div> <div class="uk-width-expand@m"></div> </div>
Building a Responsive Portfolio with UIkit:
UIkit’s Dynamic Grid
UIkit is feature-rich and has components that you can’t find in other popular frameworks. One such component is called Dynamic Grid, and can be used in conjunction with another framework’s components to create a fully functional portfolio. And that’s exactly what we’re going to do in the rest of this tutorial.
Setting Up Our Project
To create the portfolio, we’ll need the following resources:
- UIkit’s CSS, including the CSS for the Sticky component
- jQuery
- UIkit’s primary JavaScript
- UIkit’s JavaScript for the Dynamic Grid and Sticky components
It’s important to note here that the regular Grid component and Dynamic Grid have the same file name: grid.js
or grid.min.js
. But they are put in different folders, “core” and “components”, respectively.
Creating Individual Portfolio Items
After we set the stage, let’s continue by creating a container to hold and center the portfolio’s items.
<div class="uk-container uk-container-center uk-margin-top">
<div class="uk-grid-width-small-1-1 uk-grid-width-medium-1-4"
data-uk-grid="{gutter: 20}">
<!-- content... -->
</div>
</div>
We use a div
element with uk-container
and uk-container-center
classes. We also use uk-margin-top
to add some space above the content. Inside the container we create a grid with some gutter between the columns, which we specify using the data-uk-grid="{gutter: 20}"
attribute.
The uk-grid-width-small-1-1
and uk-grid-width-medium-1-4
classes tell the browser to render items differently on different devices. On smart phones the items will be shown stacked as one column, while on tablets and devices with larger screens the items will be placed in four columns.
Now, let’s make a prototype for the portfolio’s items. The next block of code creates a thumbnail with a caption at the bottom:
<div>
<figure class="uk-thumbnail uk-overlay uk-overlay-hover">
<img class="uk-overlay-fade"
src="http://placehold.it/1200x800/1e90ff/fff&text=A+4">
<div class="uk-overlay-panel uk-overlay-scale uk-flex
uk-flex-center uk-flex-middle uk-text-center">
<button class="uk-button" data-uk-modal="{target:'#project-details'}"
type="button">VIEW MORE</button>
</div>
<figcaption class="uk-thumbnail-caption">My Project</figcaption>
</figure>
</div>
To create the thumbnail, we use a figure
element with a class of uk-thumbnail
, and add a caption by adding the uk-thumbnail-caption
class to the figcaption
element.
Next, we add a “View More” button
with a class of uk-button
, which will show up on hover.
Adding a Modal Overlay to Each Item
We need some classes from UIkit’s Overlay component.
- First we add
uk-overlay
anduk-overlay-hover
classes to thefigure
element. - Then we add
uk-overlay-fade
class to theimg
element, which initially makes the image appear faded out, and fade it in on hover. - Lastly, we wrap the button with a
div
element with auk-overlay-panel
class, which serves as a container for the overlay’s content — in our case, a button.
The uk-overlay-scale
class forces the button to scale up when hovered. The rest of the classes (uk-flex uk-flex-center uk-flex-middle uk-text-center
) are used to align and center the button and the text on it.
You may have noticed the data-uk-modal="{target:'#project-details'}"
attribute inside the button
element. This is used to reference the modal, which we’re going to create in a moment.
<div id="project-details" class="uk-modal">
<div class="uk-modal-dialog">
<a class="uk-modal-close uk-close"></a>
<div class="uk-modal-header"><h2>My Project Title</h2></div>
<div class="uk-overflow-container">
<img src="http://placehold.it/1200x800/1e90ff/fff&text=My+Project+Image">
<p>Lorem Ipsum...</p>
</div>
</div>
</div>
To create a working modal dialog — which will show details about a particular item when the button is clicked — we do the following:
- Add a
div
element with auk-modal
class, andid="project-details"
attribute. We create the actual dialog by adding adiv
element with a class ofuk-modal-dialog
. - We add an
a
element withuk-modal-close uk-close
classes to create a close button. - To add a header, we use another
div
element with classuk-modal-header
. - Finally, to display the modal’s content in a scrollable container, we add one more
div
element with a class ofuk-overflow-container
.
You can copy and paste the prototype code multiple times to create the rest of the portfolio’s items. You can omit the code for the modal dialog, because it’s not essential. The primer from the first item is enough to show the desired functionality and it’s unnecessary to replicate it for the others.
Adding Filtering and Sorting
Next, we want to create a navigation bar with filtering and sorting controls. Put the following code above the markup for the portfolio’s items:
<nav data-uk-sticky id="items" class="uk-navbar">
<label class="uk-navbar-content uk-hidden-small">Filter:</label>
<ul class="uk-navbar-nav uk-hidden-small">
<li data-uk-filter="" class="uk-active"><a href="#">ALL</a></li>
<li data-uk-filter="blue"><a href="#">BLUE</a></li>
<li data-uk-filter="green"><a href="#">GREEN</a></li>
</ul>
</nav>
Here’s what is happening in the code above:
- We use a
nav
element with a class ofuk-navbar
. - We add the
data-uk-sticky
attribute to make the navigation bar stick to the top when we scroll down the content. - To add text (“Filter:”), we use a
label
element withuk-navbar-content uk-hidden-small
classes. The second class hides the text when viewed on smart phones. - We use a
ul
element withuk-navbar-nav uk-hidden-small
classes to create the filtering controls. - For each control, we use a list item with a
data-uk-filter
attribute with the corresponding filter’s name. To show all portfolio items without an applied filter, we leave the value of thedata-uk-filter
attribute empty. Also, to make the “ALL” control chosen by default, we use theuk-active
class.
For the sorting controls we do almost the same with some minor differences. Put this markup inside the nav
element, after the filtering controls:
<label class="uk-navbar-content uk-hidden-small">Sort:</label>
<ul class="uk-navbar-nav uk-hidden-small">
<li data-uk-sort="numbers">
<a href="#">NUMBERS <i class="uk-icon-sort-numeric-asc"></i></a>
</li>
<li data-uk-sort="numbers:desc">
<a href="#">NUMBERS <i class="uk-icon-sort-numeric-desc"></i></a>
</li>
<li data-uk-sort="letters">
<a href="#">LETTERS <i class="uk-icon-sort-alpha-asc"></i></a>
</li>
<li data-uk-sort="letters:desc">
<a href="#">LETTERS <i class="uk-icon-sort-alpha-desc"></i></a>
</li>
</ul>
To add a category for sorting, we use the data-uk-sort
attribute. To make the sorting descending we just append a :desc
suffix to the category’s name. We also add some icons to the controls for more aesthetics and usability. As you can see, you can create as many categories as you wish.
And now, to make everything work, we need to do two more things.
- Change the settings for our dynamic grid to:
data-uk-grid="{gutter: 20, controls: '#items', duration: 500}"
. This connects the portfolio’s items with the controls by using theid="items"
from thenav
element, and set the animation duration to 500 ms. - Connect the controls with the portfolio’s items. To do so, for each item-wrapping
div
we add the following attributes:data-uk-filter
(to connect with filter controls),data-numbers
anddata-letters
(to connect with sorting controls).
The code looks like this:
<!-- item-wrapping div -->
<div data-uk-filter="blue" data-numbers="4" data-letters="A">
<figure class="uk-thumbnail uk-overlay uk-overlay-hover">
<img class="uk-overlay-fade"
src="http://placehold.it/1200x800/1e90ff/fff&text=A+4">
<!-- etc... -->
</figure>
</div>
So far so good. But to make the portfolio truly responsive, we’ll add one more ingredient. When the portfolio is viewed on smart phones, instead of the controls, we want only a menu icon to be shown on the navigation bar. And when a user clicks this icon, we want the controls to be displayed inside a dropdown. To do this, we’ll put the following markup inside the nav
element – after the controls:
<div data-uk-dropdown="{mode:'click'}">
<a href="#" class="uk-navbar-toggle uk-visible-small"></a>
<div class="uk-dropdown uk-dropdown-navbar">
<!-- where the navbar will go -->
</div>
</div>
To summarize the above code:
- The dropdown is created with a
div
element with thedata-uk-dropdown
attribute, whose mode is set to “click”. This means that the dropdown will open on click and not on hover. - We put an
a
element inside, with a class ofuk-navbar-toggle uk-visible-small
. This creates the aforementioned menu icon and ensures that it will be visible only on smart phones. - We add another
div
element withuk-dropdown uk-dropdown-navbar
classes.
The last thing to add is the controls. We do this by putting the following markup inside the last div
we created:
<ul class="uk-nav uk-nav-navbar">
<li class="uk-nav-header">Filter:</li>
<li data-uk-filter="" class="uk-active"><a href="#">ALL</a></li>
<li data-uk-filter="blue"><a href="#">BLUE</a></li>
<li data-uk-filter="green"><a href="#">GREEN</a></li>
<li class="uk-nav-divider"></li>
</ul>
<ul class="uk-nav uk-nav-navbar">
<li class="uk-nav-header">Sort:</li>
<li data-uk-sort="numbers">
<a href="#">NUMBERS <i class="uk-icon-sort-numeric-asc"></i></a>
</li>
<li data-uk-sort="numbers:desc">
<a href="#">NUMBERS <i class="uk-icon-sort-numeric-desc"></i>
</a></li>
<li data-uk-sort="letters">
<a href="#">LETTERS <i class="uk-icon-sort-alpha-asc"></i></a>
</li>
<li data-uk-sort="letters:desc">
<a href="#">LETTERS <i class="uk-icon-sort-alpha-desc"></i></a>
</li>
</ul>
Conclusion and Demo
This is only the basic structure and functionality required for a working portfolio page. From here you can add more bells and whistles, particularly to the portfolio, or to the whole page (additional styles, other components, and so on).
For example, if your portfolio is more like an image gallery, you can use the Lightbox and/or Slideshow components. Just have some fun, experiment and see what works best for you.
Building a UIKit user interface programmatically:
The main part of the UI will be two large labels: one containing the clues the user needs to figure out, and one showing how many letters are in the word for each clue. So, it might say “A cow in a tornado” in one label and “9 Letters” in the other – with the answer being “milkshake”. As the player solves each clue, the letter count will be replaced with that answer, so they can see at a glance which ones they have solved.
Just above and to the right of those two labels will be one extra label, nice and small, which will show the user’s score.
In the middle of the screen will be a UITextField
where we’ll store the user’s current answer, plus buttons below to submit the answer or clear it.
Finally, at the bottom we’re going to make 20 (yes, twenty!) buttons, each containing different parts of the clues. So, there will be one with MIL, one with KSH, and one with AKE – the user needs to tap all three to spell MILKSHAKE. To make our layout a little easier, we’re going to place those buttons inside another UIView
that we can position centered on the screen.
The picture below shows how your finished layout should look if you’ve followed all the instructions. If you’re seeing something slightly different, that’s OK. If you’re seeing something very different, you should probably try again!
Our game is designed for iPads because we’ve got a lot of information we want to cram in. Later on, you’re welcome to try creating a second layout specifically for iPhone, and it is possible – it just takes a lot more thinking!
The first thing we’re going to do is create five properties to store the important parts of our user interface: the clues label, the answers label, the player’s current answer (the word they are spelling), their score, and all the buttons showing word pieces.
So, open ViewController.swift and add these five properties to the ViewController
class:
var cluesLabel: UILabel!
var answersLabel: UILabel!
var currentAnswer: UITextField!
var scoreLabel: UILabel!
var letterButtons = [UIButton]()
Just like in projects 4 and 7, we’re going to write a custom loadView()
method that creates our user interface in code. This will involve much more work than just creating a WKWebView
, though – we have lots of UI to create! So, we’ll tackle it piece by piece so you can see it coming together as we go.
Let’s start nice and easy: we’re going to create the main view itself as a big and white empty space. This is just a matter of creating a new instance of UIView
, giving it a white background color, and assigning that to our view controller’s view
property:
override func loadView() {
view = UIView()
view.backgroundColor = .white
// more code to come!
}
UIView
is the parent class of all of UIKit’s view types: labels, buttons, progress views, and more. Previously we assigned a WKWebView
instance directly as our view, meaning that it automatically took up all the space. Here, though, we’re going to be adding lots of child views and positioning them by hand, so we need a big, empty canvas to work with.
Placing three labels at the top
Next, let’s create and add the score label. This uses similar code to what you learned in project 6, although now we’re going to set the label’s textAlignment
property so the text is right-aligned.
Add this below the previous code, in place of the // more code to come!
comment:
scoreLabel = UILabel()
scoreLabel.translatesAutoresizingMaskIntoConstraints = false
scoreLabel.textAlignment = .right
scoreLabel.text = "Score: 0"
view.addSubview(scoreLabel)
We need to add some Auto Layout constraints to make that label be positioned neatly on the screen, and we’re going to be using anchors just like we did in project 6. These let us very clearly and descriptively place views relative to each other, however this time I want to show you one important difference: because we’ll be creating lots of constraints at the same time, we’ll be activating them all at once rather than setting isActive = true
multiple times.
This is done using the NSLayoutConstraint.activate()
method, which accepts an array of constraints. It will put them all together at once, so we’ll be adding more constraints to this call over time.
UIKit gives us several guides that we can anchor our views to. One of the most common is the safeAreaLayoutGuide
of our main view, which is the space available once you subtract any rounded corners or notches. Inside that is the layoutMarginsGuide
, which adds some extra margin so that views don’t run to the left and right edges of the screen.
In this app we’re going to be using the layoutMarginsGuide
so that our views are indented a little on each edge, but we’ll also be adding some extra indenting to make the whole thing look better on-screen.
So, add this below the previous code:
NSLayoutConstraint.activate([
scoreLabel.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),
scoreLabel.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor),
// more constraints to be added here!
])
Notice the way I’m pinning the label to view.layoutMarginsGuide
– that will make the score label have a little distance from the right edge of the screen.
Tip: Remember that you’re setting anchors as an array, so make sure you include a comma after each one.
To avoid confusion, here’s what you should have so far:
override func loadView() {
view = UIView()
view.backgroundColor = .white
scoreLabel = UILabel()
scoreLabel.translatesAutoresizingMaskIntoConstraints = false
scoreLabel.textAlignment = .right
scoreLabel.text = "Score: 0"
view.addSubview(scoreLabel)
NSLayoutConstraint.activate([
scoreLabel.topAnchor.constraint(equalTo: view.layoutMarginsGuide.topAnchor),
scoreLabel.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor, constant: 0),
])
}
We’ll be adding lots more view code before the call to NSLayoutConstraint.activate()
, and lots more constraints code inside that array being passed to NSLayoutConstraint.activate()
.
If you run the app now you should see “Score: 0” nestled in the top-right corner. If you don’t see that, please check your code otherwise the rest of this project will be very confusing indeed!
Next we’re going to add the clues and answers labels. This will involve similar code to the score label, except we’re going to set two extra properties: font
and numberOfLines
. The font
property describes what kind of text font is used to render the label, and is provided as a dedicated type that describes a font face and size: UIFont
. numberOfLines
is an integer that sets how many lines the text can wrap over, but we’re going to set it to 0 – a magic value that means “as many lines as it takes.”
Add this code below the code to create the label, but before the Auto Layout code:
cluesLabel = UILabel()
cluesLabel.translatesAutoresizingMaskIntoConstraints = false
cluesLabel.font = UIFont.systemFont(ofSize: 24)
cluesLabel.text = "CLUES"
cluesLabel.numberOfLines = 0
view.addSubview(cluesLabel)
answersLabel = UILabel()
answersLabel.translatesAutoresizingMaskIntoConstraints = false
answersLabel.font = UIFont.systemFont(ofSize: 24)
answersLabel.text = "ANSWERS"
answersLabel.numberOfLines = 0
answersLabel.textAlignment = .right
view.addSubview(answersLabel)
Using UIFont.systemFont(ofSize: 24)
will give us a 24-point font in whatever font is currently being used by iOS. This was Helvetica in the early days of iOS, then moved to Helvetica Neue and finally San Francisco. Asking for the system font means we’ll get whatever is the standard today, but our UI will update automatically if Apple makes more changes in the future.
To position those in such a way that they look great on a variety of iPad sizes – from iPad Mini up to the 12.9-inch iPad Pro – we’re going to set some anchors:
- The tops of the clues and answers labels will be pinned to the bottom of the score label.
- The clues label will be pinned to the leading edge of the screen, indented by 100 points so that it looks neater.
- The clues label will have a width anchor set to 0.6 of the width of the main view, so that it takes up 60% of the screen. We need to subtract 100 from this to account for the indent.
- The answers label will be pinned to the trailing edge of the screen, then also indented by 100 points to match the clues label.
- The answers label will have a width anchor of 0.4 of the width of the main view, so that it takes up the remaining 40% of the screen. Again, that needs to have 100 taken away to account for the indent.
- Finally, we’re going to make the height of the answers label match the height of the clues label.
I realize that might sound like a lot of work, but this kind of thing is where Auto Layout anchors really shine. Just remember: it takes the multiplier into account first, then the constant.
Add these constraints to the array we’re activating – I’ve added comments just to be sure:
// pin the top of the clues label to the bottom of the score label
cluesLabel.topAnchor.constraint(equalTo: scoreLabel.bottomAnchor),
// pin the leading edge of the clues label to the leading edge of our layout margins, adding 100 for some space
cluesLabel.leadingAnchor.constraint(equalTo: view.layoutMarginsGuide.leadingAnchor, constant: 100),
// make the clues label 60% of the width of our layout margins, minus 100
cluesLabel.widthAnchor.constraint(equalTo: view.layoutMarginsGuide.widthAnchor, multiplier: 0.6, constant: -100),
// also pin the top of the answers label to the bottom of the score label
answersLabel.topAnchor.constraint(equalTo: scoreLabel.bottomAnchor),
// make the answers label stick to the trailing edge of our layout margins, minus 100
answersLabel.trailingAnchor.constraint(equalTo: view.layoutMarginsGuide.trailingAnchor, constant: -100),
// make the answers label take up 40% of the available space, minus 100
answersLabel.widthAnchor.constraint(equalTo: view.layoutMarginsGuide.widthAnchor, multiplier: 0.4, constant: -100),
// make the answers label match the height of the clues label
answersLabel.heightAnchor.constraint(equalTo: cluesLabel.heightAnchor),
If you run the code now you’ll see “CLUES” and “ANSWERS” near the top of the screen.
Temporarily – just so you can follow along and see how everything works! – try adding this code after the call to activateConstraints()
:
cluesLabel.backgroundColor = .red
answersLabel.backgroundColor = .blue
That will make our two big labels stand out more clearly, which will be helpful while we’re building our UI.
Entering answers
Next we’re going to add a UITextField
that will show the user’s answer as they are building it. You might think this is a good place to use another UILabel
particularly because we want players to build words by tapping letter buttons rather than typing into a box. However, this lets me introduce you to the placeholder
property of text fields, which draws gray prompt text that the user can type over – it looks really nice, and gives us space to provide some instructions to users.
As with our labels we’re also going to adjust the font and alignment of the text field, but we’re also going to disable user interaction so the user can’t tap on it – we don’t want the iOS keyboard to appear.
Add this code alongside the other views:
currentAnswer = UITextField()
currentAnswer.translatesAutoresizingMaskIntoConstraints = false
currentAnswer.placeholder = "Tap letters to guess"
currentAnswer.textAlignment = .center
currentAnswer.font = UIFont.systemFont(ofSize: 44)
currentAnswer.isUserInteractionEnabled = false
view.addSubview(currentAnswer)
The only new part is setting isUserInteractionEnabled
to false, which is what stops the user from activating the text field and typing into it.
As for constraints, we’re going to make this text field centered in our view, but only 50% its width – given how many characters it will hold, this is more than enough. We’re also going to place it below the clues label, with 20 points of spacing so the two don’t touch.
Add this to your constraints array:
currentAnswer.centerXAnchor.constraint(equalTo: view.centerXAnchor),
currentAnswer.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5),
currentAnswer.topAnchor.constraint(equalTo: cluesLabel.bottomAnchor, constant: 20),
Run the app again, and you’ll see “Tap letters to guess” in gray underneath the red and blue labels – this is coming together slowly!
Below the text field we’re going to add two buttons: one for the user to submit their answer (when they’ve entered all the letters they want), and one to clear their answer so they can try something else.
To create a UIButton
in code you need to know two things:
- Buttons have various built-in styles, but the ones you’ll most commonly use are
.custom
and.system
. We want the default button style here, so we’ll use.system
. - We need to use
setTitle()
to adjust the title on the button, just like we did withsetImage()
in project 2.
Add this to our view creation code:
let submit = UIButton(type: .system)
submit.translatesAutoresizingMaskIntoConstraints = false
submit.setTitle("SUBMIT", for: .normal)
view.addSubview(submit)
let clear = UIButton(type: .system)
clear.translatesAutoresizingMaskIntoConstraints = false
clear.setTitle("CLEAR", for: .normal)
view.addSubview(clear)
Note: We don’t need to store those as properties on the view controller, because we don’t need to adjust them later.
In terms of the constraints to add for those buttons, they need three each:
- One to set their vertical position. For the submit button we’ll be using the bottom of the current answer text field, but for the clear button we’ll be setting its Y anchor so that its stays aligned with the Y position of the submit button. This means both buttons will remain aligned even if we move one.
- We’re going to center them both horizontally in our main view. To stop them overlapping, we’ll subtract 100 from the submit button’s X position, and add 100 to the clear button’s X position. “100” isn’t any sort of special number – you can experiment with different values and see what looks good to you.
- We’re going to force both buttons to have a height of 44 points. iOS likes to make its buttons really small by default, but at the same time Apple’s human interface guidelines recommends buttons be at least 44×44 so they can be tapped easily.
Here are the constraints required to bring those rules to life – please add this to your constraints list:
submit.topAnchor.constraint(equalTo: currentAnswer.bottomAnchor),
submit.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: -100),
submit.heightAnchor.constraint(equalToConstant: 44),
clear.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 100),
clear.centerYAnchor.constraint(equalTo: submit.centerYAnchor),
clear.heightAnchor.constraint(equalToConstant: 44),
Buttons… buttons everywhere!
Are you feeling tired yet? It’s hard work, isn’t it? Don’t get me wrong – building user interface programmatically has many advantages, but it is certainly verbose.
Fortunately we’re near the end now, and all that remains is to add letter buttons at the bottom of the user interface. We need a lot of these – 20, to be precise – and we need to make sure they are positioned neatly on the screen.
With complicated layouts like this one the smart thing to do is wrap things in a container view. In our case this means we’re going to create one container view that will house all the buttons, then give that view constraints so that it’s positioned correctly on the screen.
This is just going to be a plain UIView
– it does nothing special other than host our buttons. So, add this code below our previous view creation code:
let buttonsView = UIView()
buttonsView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(buttonsView)
As this thing is the last view in our view (excluding the buttons inside it, but they don’t play a part in our Auto Layout constraints), we need to give it more constraints so that Auto Layout knows our hierarchy is complete:
- We’re going to give it a width and height of 750×320 so that it precisely contains the buttons inside it.
- It will be centered horizontally.
- We’ll set its top anchor to be the bottom of the submit button, plus 20 points to add a little spacing.
- We’ll pin it to the bottom of our layout margins, -20 so that it doesn’t run quite to the edge.
Add these final constraints to our constraints array:
buttonsView.widthAnchor.constraint(equalToConstant: 750),
buttonsView.heightAnchor.constraint(equalToConstant: 320),
buttonsView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
buttonsView.topAnchor.constraint(equalTo: submit.bottomAnchor, constant: 20),
buttonsView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor, constant: -20)
Just for testing purposes, give that new view a green background color:
buttonsView.backgroundColor = .green
We haven’t added the buttons inside that view just yet, but please run the app now – I think you’ll find the result interesting.
What you’ll see is that our layout has changed quite dramatically: everything that used to be pinned to the top has now been pulled downwards. This isn’t a mistake, or an Auto Layout bug, but is the natural result of all the rules we’ve laid down:
- Our buttons view should be pinned to the bottom and be exactly 320 points high.
- The submit button should be above the buttons view.
- The current answer text field should be above the submit button.
- The answers label should be above the current answer text field.
- The score label should be above the answers label.
- The score label should be pinned to the top of our view.
In short, we have the buttons view pinned to the bottom and the score label pinned to the top, with all our other views in between.
Before we added the final buttons view, Auto Layout had no special idea of how big any of the views should be, so it used something called the intrinsic content size – how big each view needs to be to show its content. This resulted in our views being neatly arranged at the top. But now we have a complete vertical stack, pinned at the top and bottom, so UIKit needs to fill the space in between by stretching one or more of the views.
Every view in all our UIKit layouts has two important properties that tell UIKit how it can squash or stretch them in order to satisfy constraints:
- Content hugging priority determines how likely this view is to be made larger than its intrinsic content size. If this priority is high it means Auto Layout prefers not to stretch it; if it’s low, it will be more likely to be stretched.
- Content compression resistance priority determines how happy we are for this view to be made smaller than its intrinsic content size.
Both of those values have a default: 250 for content hugging, and 750 for content compression resistance. Remember, higher priorities mean Auto Layout works harder to satisfy them, so you can see that views are usually fairly happy to be stretched, but prefer not to be squashed. Because all views have the same priorities for these two values, Auto Layout is forced to pick one to stretch – the score at the top.
Now, all this matters because we’re going to adjust the content hugging priority for our clues and answers labels. More specifically, we’re going to give them a priority of 1, so that when Auto Layout has to decide which view to stretch they are first in line.
Add these two lines of code after the code that creates cluesLabel
and answersLabel
:
cluesLabel.setContentHuggingPriority(UILayoutPriority(1), for: .vertical)
answersLabel.setContentHuggingPriority(UILayoutPriority(1), for: .vertical)
Run the app now and you’ll see a big difference: the two labels now take up much more space, and the rest of our user interface looks more normal.
Now that our user interface looks as it should, let’s create the final piece of our layout: the letter buttons that sit inside buttonsView
.
We have 20 buttons to create across four rows and five columns, which is the perfect time to use some nested loops: create and configure each button, then position it inside the buttons view.
However, we’re going to rely on a lovely feature of Auto Layout to make this whole process much easier: we’re not going to set translatesAutoresizingMaskIntoConstraints
to false for these buttons, which means we can give them a specific position and size and have UIKit figure out the constraints for us.
So, this actual button creation isn’t as hard as you might think:
- Set constants to represent the width and height of our buttons for easier reference.
- Loop through rows 0, 1, 2, and 3.
- Loop through columns 0, 1, 2, 3, and 4.
- Create a new button with a nice and large font – we can adjust the font of a button’s label using its
titleLabel
property. - Calculate the X position of the button as being our column number multiplied by the button width.
- Calculate the Y position of the button as being our row number multiplied by the button height.
- Add the button to our
buttonsView
rather than the main view.
As a bonus, we’re going to add each button to our letterButtons
array as we create them, so that we can control them later in the game.
Calculating positions of views by hand isn’t something we’ve done before, because we’ve been relying on Auto Layout for everything. However, it’s no harder than sketching something out on graph paper: we create a rectangular frame that has X and Y coordinates plus width and height, then assign that to the frame
property of our view. These rectangles have a special type called CGRect
, because they come from Core Graphics.
As an example, we’ll be calculating the X position for a button by multiplying our fixed button width (150) by its column position. So, for column 0 that will give an X coordinate of 150×0, which is 0, and for column 1 that will give an X coordinate of 150×1, which is 150 – they will line up neatly.
Add this code after the call to NSLayoutConstraint.activate()
:
// set some values for the width and height of each button
let width = 150
let height = 80
// create 20 buttons as a 4x5 grid
for row in 0..<4 {
for col in 0..<5 {
// create a new button and give it a big font size
let letterButton = UIButton(type: .system)
letterButton.titleLabel?.font = UIFont.systemFont(ofSize: 36)
// give the button some temporary text so we can see it on-screen
letterButton.setTitle("WWW", for: .normal)
// calculate the frame of this button using its column and row
let frame = CGRect(x: col * width, y: row * height, width: width, height: height)
letterButton.frame = frame
// add it to the buttons view
buttonsView.addSubview(letterButton)
// and also to our letterButtons array
letterButtons.append(letterButton)
}
}
That’s the last of our code complete, so please remove the temporary background colors we gave to cluesLabel
, answersLabel
, and buttonsView
, then run your code to see how it all looks.
Advantages:
Most notably, UI kits can save you time and money by allowing designers to use their time more efficiently. When you don’t have to worry about the standard details, you can optimize your work by focusing on the unique features of the specific site, app, or product you’re working on. Though it can be an investment to purchase or create a premium UI kit, it’s worth it, especially if you’re going to use it for several designs or sites.
When everyone knows exactly what size your CTAs should be and what color the cancel buttons are, your product is more consistent throughout. This allows your users to learn your product quicker and reduces cognitive load. This reliable documentation also encourages newcomers (to the product or company) to quickly hop on board, giving them a helpful glimpse into your rules and style preferences. Think of it as the true north for your UI.
Last but not least, UI kits give you the ability to update styles quickly, easily, and on the fly. If a client changes the color of their app or site, no big deal. A UI kit allows you to keep everything organized and categorized so you know that all your CTAs are blue with a 2px stroke and a 5px dropshadow.
Disadvantages:
The disadvantages of UI kits are more nuanced, but still worth considering before you dive in.
Depending on the UI kit you create or use, you could be locked into specific components, or be missing certain ones completely. Not all kits are comprehensive, and if you’re building yours as you go, you’ll have some gaps. It’s not a huge deal, but it could rob your efficiency instead of boosting it.
Matching styles from your brand to a different UI kit can be time-consuming. Let’s say you find a great UI kit that has rounded edges on all the elements, but your client’s brand has square edges throughout. Smaller components may be easy to change, but matching the style throughout the entire kit could take a lot of work. If a kit is dramatically different from your style, this could mean more work, time, and money.
-UIkit A lightweight and modular front-end framework for developing fast and powerful web interfaces.UIkit gives you a comprehensive collection of HTML, CSS, and JS components which is simple to use, easy to customize and extendable.
UIkit is open source and MIT licensed. It is absolutely free of charge and you can use, copy, merge, publish and distribute the framework without any limitations.
Features
In addition to the core app behaviors, UIKit provides support for the following features:
· A view controller model to encapsulate the contents of your user interface
· Support for handling touch- and motion-based events
· Support for a document model that includes iCloud integration;
· Graphics and windowing support, including support for external displays;
· Support for managing the app’s foreground and background execution
· Printing support;
· Support for customizing the appearance of standard UIKit controls
· Support for text and web content
· Cut, copy, and paste support
· Support for animating user-interface content
· Integration with other apps on the system through URL schemes and framework interfaces
· Accessibility support for disabled users
· Support for the Apple Push Notification service;
· Local notification scheduling and delivery;
· PDF creation
· Support for using custom input views that behave like the system keyboard
· Support for creating custom text views that interact with the system keyboard
· Support for sharing content through email, Twitter, Facebook, and other services
In addition to providing the fundamental code for building your app, UIKit also incorporates support for some device-specific features,such as the following:
· The built-in camera (where present)
· The user’s photo library
· Device name and model information
· Battery state information
· Proximity sensor information
· Remote control information from attached headsets
-Major Features of UIkit:
LESS
UIkit is developed in LESS to write well-structured, extendable code which is easy to maintain.
Components
A collection of small, responsive components using consistent and conflict-free naming conventions.
Customizer
UIkit’s very basic style can be extended with themes and is easy to customize to create your own look.
Responsive
With the mobile-first approach UIkit provides a consistent experience from phones and tablets to desktops.
Videos
Installing the “UIkit for Gantry5” atom on Joomla