Kinderswift 5: Make Me a Double

This time, we review integers, and look at the Double type.

Transcript

Welcome back to kinder swift. This lesson we will look at numbers that have decimal points, which are known as Doubles. To start, let’s make a new playground. Click File>New>playground.
Name the new playground Kinderswift5Playground and save the file.

Remove what is already there so we have a fresh page.

To review the integers, or Int type as we will call it, add the following code to the playground. Pause the video if you need to.

//Int Type 
let myInteger = 4
var intResult = 0

intResult = myInteger + 5
intResult = myInteger - 5
intResult = myInteger * 5
intResult = 5 / myInteger 
intResult = myInteger / 5

We assigned 4 to a constant integer called myInteger. We then initialized to zero a variable called intResult.

Just like before, we added five to myInteger‘s value of four and got 9. We subtracted four from five and got -1. We multiplied 5 and got 20.

As we discussed last time we have some problems with integer division. Five divided by myInteger’s value of 4 equals one. Four divided by five equals zero.

Most of the time we want a decimal value so that 5/4 = 1.25 and 4/5 = 0.8.

Variables and constants have types. Up to now we have only worked with the Type Int. There are other types. One of the most frequent ones used for mathematics and graphics is Double. There are two ways to declare a double, one of which we’ll cover in our next lesson. The easy way is just add a decimal point to our initial value in a constant or variable. So for example type this out.

//Double Type
let myDouble = 4.0
var doubleResult = 0.0

In the results column, we get 4.0 and 0.0. The decimal point tells us this is a Double. These are now declared doubles.
Math works the same. Try adding:

doubleResult = myDouble + 5.0

We get 9.0. Now try subtraction:

doubleResult = myDouble - 5.0

We get -1.0. Now multiplication:

doubleResult = myDouble * 5.0

we get 20.0. And now for the good part. try these two division

doubleResult = myDouble / 5.0
doubleResult = 5.0 / myDouble

Now 4/5 = 0.8 and 5/4 equals 1.25.
When working with literal doubles you can write any number with a decimal point of course, so you can calculate these:

doubleResult = 2.4/3.0
doubleResult = 3.141/2.71

Doubles will allow increments as well. try:

doubleResult += 3.0

What you can’t do is mix types. YOu cant do any of these operations with both a Int and a double. type this:

//Can't mix types:
doubleResult = myDouble + myInteger

And you will get an error. We may want to add Integers and Doubles t times, so the next lesson will tackle that problem.
I’m

Swift Swift: Basic Auto Layout for iOS8

This is one of several videos I’m making about Auto Layout and Size classes. In this first video, I’ll put together a user interface and with Auto Layout. I’ll also show how to use the preview mode so you can see the UI on any iOS device without running the simulator.

For an in-depth look at what I am doing here you can also check out this post on Auto Layout

KinderSwift 4: Increments and Math Operators

In this episode, we’ll finish looking at the integer math operators, and talk a bit about how to count by one and two using increment operators.

Transcript

Welcome back to Kinderswift. Let’s continue from where we left off last time.In our last session, we used the let and var statements.
let and var statements are called definitions since they define the identifier and some information about the identifier. Once we do that we can use the identifier without var in an assignment. In a definition we do a special assignment called initializing which sets the first value of an identifier. For a constant, this value will be the only value.

Last time we used assignment to add the current value of myResult and assign a new value to myResult.

There is a special case of this we call an increment. The basic increment is this:

myResult = myResult + 1

We take myResult, add one and assign it back for a new myResult. We will use increments for counting. There are other ways to do the same thing. Type

myResult += 1

The += operator increments for us by the value on the left side of the equals. So here we increment by 1. It is the same as writing what we did just above. We can change the increment as well. If we wanted to increment by 2, we can write this:

myresult += 2

Which is the same as

myresult = myresult + 2

There is one way even simpler. That is the ++ operator. this always adds 1 to the value, but we need no equal sign.

++myResult

Increments myResult by one and then shows the value of myResult.

You can put the plus plus at the end too, but this get a little tricky.
myResult++

Shows the result and then increments the value. In the playground, We need to show the result again.
and then we see the increment.

That is not all we can do. we can subtract, multiply, and divide as well. for example

myResult = myNumber - myOtherNumber

Subtracts myNmber from myOtherNumber.

We use an asterisk for multiplication so:

myResult = myNumber * myOtherNumber

multiplies myNumber by myOtherNumber.

We use a forward slash to divide. Try

myResult = myNumber / myOtherNumber.

This divides myNumber by myOtherNumber giving an integer result.

Let’s use some literal numbers to see why this is important :

Dividing four by 2 gets us two as expected.

Dividing five by two also gets us two, since we are using integers. The remainder gets cut off.

So far I’ve kept the examples whole numbers. Try this:

myResult = 2 - 4

We get a negative number for a result. We can use negative numbers in calculations as well. This subtraction is the same as

myResult = 2 + -4

Which brings up a possible error you might get. Be careful with spacing. type this:
myResult = 2 + -4

We get an error since Swift thinks this reads myResult equals 2 negative 4. It wants an operator, not two numbers. Add a space between the minus and the 4.
myResult = 2 + -4

The error disappears.

Now try this: myResult = 1/4

We get a result of 0. So far we are only working with integers. Like 5 / 2 above, any non integer part of division is dropped off. If we need the remainder, often called a mod in Computer jargon we use the % sign. So 1 % 4 equals 1. and 5 % 2 also equals 1.

There are a few times we use a mod for calculations. Most of the time, I want 5 divided by two to be 1.5 and one divided by four to be 0.25. That requires something else called a Double, and that will be the topic for our next lesson.

Swift Swift: Using UIWebViews in Swift

[Updated to Swift2.0/iOS9 — 10/17/15 SJL]
There are times we need formatted content. There are also times we need to access content on the web. The UIWebView is a very useful view for both. In this week’s lesson we’ll explore how to use this view in a variety of applications.

One warning: Since this is about web browsers. I will be using HTML/CSS. Since this lesson is about Swift and Xcode and not a web design I’ll present this code as-is. If you do not know any HTML there are more than a few courses available to you to get you up to speed.

Set Up the Scene

Open a new single view project called SwiftWebView. Make this project Universal instead of our usual iPhone. This project will work on both iPads and iPhones. Go to the storyboard. Drag a Web View and a Tool Bar onto the storyboard. This application will use auto layout. Start by aligning the toolbar with the blue lines on the storyboard at the top, then align the web view underneath it to take up the rest of the space on the view. Add four bar buttons the the toolbar and label them as below. Use a few bar spacers to space them out. When done it should look something like this:
Screenshot 2014-10-27 07.18.28

Now click the toolbar and the pin Screenshot 2014-10-27 07.25.10 button on the storyboard. Click on the top left and right i-beams and then set the pop up to this, ignoring the bottom constraint:

2015-10-17_20-37-55

Do the same for the web view and set it to this:

2015-10-17_20-37-55

Once done, you may get warnings from Xcode that the frames will not be the same a run time. If so, first click one of the objects on the story board, then click the Screenshot 2014-10-28 17.46.59 and select Update Frames to refresh the frame. Doe the same for the other object if there are still warnings.

Wire Up the Project

Open the assistant editor, and control drag the web view into the ViewController class. Name the outlet myWebview.

Add four actions, one for each of the bar buttons as helloPizza, makeAppPie, back and forward . When done, your code should look like this:

class ViewController: UIViewController {

    @IBOutlet weak var myWebView: UIWebView!
//Navigation in a web view
    @IBAction func back(sender: AnyObject) {

    }

    @IBAction func forward(sender: AnyObject) {

    }

// Go to a internal or external html page
    @IBAction func makeAppPie(sender: AnyObject) {

    }

    @IBAction func helloPizza(sender: UIBarButtonItem) {

    }

    override func viewDidLoad() {

    }

}

A Web View From a String

There are several ways to use a web view. Before attributed strings, this was the only way to get formatted text. The developer would write a string of text in HTML and send it to a UIWebview using the method loadHTMLString. Change the viewDidLoad method to this:

overridefuncviewDidLoad() {
        super.viewDidLoad()
        letmyHTMLString:String! = "
<h1>Hello Pizza!</h1>

"
        myWebView.loadHTMLString(myHTMLString, baseURL: nil)
    }

Line 3 makes a optional string, since the loadHTMString method requires one. Line 4 loads the string, and has a second parameter baseURL, which sets the base URL path for the HTML. Usually we set this to nil but if you had files you wanted to load like images or a style sheet, this would give the default path for the files.
Build and run:

Screenshot 2014-10-28 06.24.09

That was pretty boring, so let’s add some more HTML code, replace the string with this, all without a line break.

letmyHTMLString:String! = "
<h1 style=\"font-family: Helvetica\">Hello Pizza</h1>

Tap the buttons above to see <strong>some cool stuff</strong> with <code>UIWebView</code>

<img src=\"https://apppie.files.wordpress.com/2014/09/photo-sep-14-7-40-59-pm_small1.jpg\">"

You’ll notice a few places where we used the Quote escape sequence \". We need to add quotes in a few places and a backslash followed by a quote allows us to do so within a string. Build and Run. That is a little better:

Screenshot 2014-10-28 18.22.24

A Web View and CSS From Files

Trying to make something formatted from a string is not easy. Our work would be easier if we had the HTML in a separate file. Even better would be an external style sheet. Tap Command-N on the keyboard or File>New>File… from the drop-down menu to make a new file. Make a blank file by going to Other under iOS and Empty.
Screenshot 2014-10-28 05.51.55
Click next and then name the file myHTML.html. Save the file. In the blank file add the following code:

<!DOCTYPE html>
<html>
<head>
    <title>Hello Pizza! Home</title>
    <link rel="stylesheet" href="myCSS.css" type="text/css">
</head>
<body>
<!-- Site navigation menu -->

<div class="navbar">
    <a href="index.html">Home</a>
    <a href="musings.html">Toppings</a>
    <a href="town.html">Crust</a>
    <a href="links.html">Ovens</a>
</div>


<div class="content">
    <!-- Main content -->

<h1>Hello Pizza!</h1>



This is a site for the love of all things pizza!

    


But we are not just pizza, we are with anything on a flatbread. So look around and you will find naan, flatbreads, pitas and tortilla related stuff too!!!

    


If that is not enough, check our sister site <a href="pie">Hello Pie</a>

    
    <img src="https://apppie.files.wordpress.com/2014/09/photo-sep-14-7-40-59-pm_small1.jpg" alt="" />
    <!-- Sign and date the page, it's only polite! -->
</div>


<address>Made 16 October 2015
    by makeapppie.com.</address>

</body>

Back in the ViewController.swift file change the helloPizza method to this:

    @IBAction func helloPizza(sender: UIBarButtonItem) {
        let myURL = NSBundle.mainBundle().URLForResource("myHtml", withExtension: "html")
        let requestObj = NSURLRequest(URL: myURL!)
        myWebView.loadRequest(requestObj)
    }

Line 2 creates a url for myHTML.html from what is called the main bundle. The main bundle is the directory we place all of our code files in XCode for a specific project. The main bundle changes location depending on the device. Instead of giving a literal path, we use this relative indicator. Line 3 creates an NSURLRequest, an object we feed into the loadRequest method in line 4. The loadRequest loads the HTML code into the UIWebView. Build and run this. Click the Pizza button and you get this:
Screenshot 2014-10-28 06.21.42
This view is not that pretty, but we can add some CSS to clean it up a bit. Create another blank file as you did before, named myCSS.css and add the following to the new file:

body {
    color: #eeeeee;
    background: #a0a088;
    font-family:Helvetica}
h1 {
    color: #dd1111;
    font-family:Chalkduster;
    font-size: 18pt}
a{
    font-family:Helvetica;
    font-weight: bold;
    color: #ffffaa;
    text-decoration:none;
    padding-left: 5px;
}
img{
    padding-left:0;
    max-width: 90%;
    max-height: 90%;
    box-shadow: 3px 3px 3px 0px #202020
}
.navbar {
    background-color: #000000;
    color: white;
    position: absolute;
    top: 0em;
    left: 0em;
    width: 100% }
.content{
    padding-left: 1em;
    padding-top: 1em;
}

The HTML code  in myHtml.Html

<link rel="stylesheet" href="myCss.css" type="text/css">

assumes that the baseURL is the bundle. Build and run and we get a better formatted web view:
Screenshot 2014-10-28 06.22.15

A Web View From a Website

Many times we will want to pull something directly from the web. Instead of getting our url from a bundle, we just type it explicitly to a web address. For example, change the makeAppPie code to this:

    @IBAction func makeAppPie(sender: AnyObject) {
        let url = NSURL(string: "http://makeapppie.com")
        let requestObj = NSURLRequest(URL: url!)
        myWebView.loadRequest(requestObj)
    }

Build and run, and tap the AppPie button. You will get an error in the error console, and no web page.
2015-10-17 12:57:28.540 SwiftWebView[22360:1181188] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

Starting in iOS9 Apple added extra security to NSURLRequest. In another post I’ll describe this in detail. We can shut down this security with a entry in the plist.info file. IN the Navigator, right-click on plist.info. Select Open As > Source Code.

2015-10-17_12-29-43

 

In the XML code that appears add this just under the first tag:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key><true/>
    </dict>

Build and run again. Press AppPie. Now we get the web page.

2015-10-17_20-33-36

 

It may take a while, particularly if using the simulator for the web page to display. This is one of those places where you might want to avoid any other processing while running your webview.

Web View Navigation

A problem with what we’ve got so far is navigation. I can go to links on MakeAppPie, and dive into an article, but I can t go backwards. UIWebview has methods to handle that. Change the back and forward button actions to this:

//code to do navigation in the web view
    @IBAction func back(sender: AnyObject) {
        if myWebView.canGoBack{
            myWebView.goBack()
        }
    }

    @IBAction func forward(sender: AnyObject) {
        if myWebView.canGoForward{
            myWebView.goForward()
        }
    }

In each case we check the property canGoForward or canGoBack. If we can go forward or back, we then use the method to do so. Build and run we can now use the back and forward buttons to navigate the web browser when there is a page to go forward or backward to.

The Whole Code

//
//  ViewController.swift
//  SwiftWebView
//
//  Created by Steven Lipton on 10/16/15.
//  Copyright © 2015 Steven Lipton. All rights reserved.
//

import UIKit

class ViewController:UIViewController {
    
    @IBOutlet weak var busyindicator:UIActivityIndicatorView!
    
    @IBOutlet weak var myWebView: UIWebView!
    //code to do navigation in the web view
    @IBAction func back(sender:AnyObject) {
    if myWebView.canGoBack{
    myWebView.goBack()
    }
    }
    
    @IBAction func forward(sender:AnyObject) {
    if myWebView.canGoForward{
    myWebView.goForward()
    }
    }
    // go to a internal or external html page
    /* be sure to add this to the info.plist
    <key>NSAppTransportSecurity</key>
        <dict>
            <key>NSAllowsArbitraryLoads</key><true/>
        </dict>

    */
    @IBAction func makeAppPie(sender:AnyObject) {
        let url = NSURL(string: "https://makeapppie.com/2014/10/28/swift-swift-using-uiwebviews-in-swift/)
        let requestObj = NSURLRequest(URL:url!)
        myWebView.loadRequest(requestObj)
    }
    
    
    
    @IBAction func helloPizza(sender:UIBarButtonItem) {
        let myURL = NSBundle.mainBundle().URLForResource("myHtml",withExtension: "html")
        let requestObj = NSURLRequest(URL:myURL!)
        myWebView.loadRequest(requestObj)
    }
    
    override func viewDidLoad() {
     super.viewDidLoad()
     //let myHTMLString:String! = "</pre>
<h1>Hello Pizza!</h1>
<pre>"
       let myHTMLString : String! = "
<h1 style=\"font-family: Helvetica\">Hello Pizza</h1>

Tap the buttons above to see <strong>some cool stuff</strong> with <code>UIWebView</code>

<img src=\"https://apppie.files.wordpress.com/2014/09/photo-sep-14-7-40-59-pm_small1.jpg\">"
        myWebView.loadHTMLString(myHTMLString, baseURL: nil)
    }

}

myHtml.html

<!DOCTYPE html>
<html>
<head>
    <title>Hello Pizza! Home</title>
    <link rel="stylesheet" href="myCSS.css" type="text/css">
</head>
<body>
<!-- Site navigation menu -->

<div class="navbar">
    <a href="index.html">Home</a>
    <a href="musings.html">Toppings</a>
    <a href="town.html">Crust</a>
    <a href="links.html">Ovens</a>
</div>


<div class="content">
    <!-- Main content -->

<h1>Hello Pizza!</h1>



This is a site for the love of all things pizza!

    


But we are not just pizza, we are with anything on a flatbread. So look around and you will find naan, flatbreads, pitas and tortilla related stuff too!!!

    


If that is not enough, check our sister site <a href="pie">Hello Pie</a>

    
    <img src="https://apppie.files.wordpress.com/2014/09/photo-sep-14-7-40-59-pm_small1.jpg" alt="" />
    <!-- Sign and date the page, it's only polite! -->
</div>


<address>Made 16 October 2015
    by makeapppie.com.</address>

</body>

myCSS.css

body {
    color: #eeeeee;
    background: #a0a088;
    font-family:Helvetica}
h1 {
    color: #dd1111;
    font-family:Chalkduster;
    font-size: 18pt}
a{
    font-family:Helvetica;
    font-weight: bold;
    color: #ffffaa;
    text-decoration:none;
    padding-left: 5px;
}
img{
    padding-left:0;
    max-width: 90%;
    max-height: 90%;
    box-shadow: 3px 3px 3px 0px #202020
}
.navbar {
    background-color: #000000;
    color: white;
    position: absolute;
    top: 0em;
    left: 0em;
    width: 100% }
.content{
    padding-left: 1em;
    padding-top: 1em;
}

KinderSwift Episode 3: Variable Assignment in the Xcode Playground

In this episode of our beginner’s series on Swift, we will dive into programming with the most fundamental part: assignment of values to identifiers. We’ll use the new Xcode playground feature to explore var and let. We’ll learn how to add numbers and a few tips about common syntax errors and the Xcode’s autocomplete feature

Edited Transcript

Welcome back to episode 3 of KinderSwift. In this lesson we’ll begin using the playground to learn to code.

Open Xcode. If you have any other projects open, close them. and if necessary restart Xcode.

If you don’t see the welcome page hit Shift-command-1 on the keyboard.

kinderSwift 3 open frame welcome

When you have a welcome page, Click Get started with a playground.
kinderSwift 3 click playground

A new window asks you about the playground. Name the playground MyKinderswiftPlayground, and make sure the drop down says iOS.

kinderSwift 3 open playground

Click Next and save it in the same place we saved the project from last time, which should be the default setting.Click Create, and we are in the playground.
frame1shot

 

The playground is an interactive environment that lets you see what is happening immediately. In this early part of your coding experience, it will be a lot easier and faster to use the playground than coding an app.

Delete the line right under import UIKit. Leave the UIKit line there. That is what makes our code work.

The first thing I’d like to teach you is this

//this is a comment

That is, as it says, a comment. Swift ignores it, but it is a great way for us to put notes to ourselves and others about what we are doing in our code. Now type this:

let myNumber = 4

This assigns the integer 4 to the identifier constant myNumber.
Now what does that mean? Let’s break this down piece by piece.

We have the keyword let. Keywords are words in a computer language which the system knows is a command. let is a command to make a constant, which is a value that will always stay the same.

kinderSwift 3 let description

After the let we have a space. Spaces in programming languages are as important as in written languages because they tell us we are going to the next word.
We then have the identifier myNumber, which is a way of naming a value. In Swift we write identifiers usually like this where we squish words together without spaces and capitalize where we are supposed to have a space.

Constants and variables like this will start with a lower case letter, to distinguish it from the types and classes we’ll learn in a few sections.

The equals sign acts as the assignment operator, another keyword that says take the value following this and make it the value of the identifier before it.

kinderSwift 3 equals description

What that means is myNumber is 4, and I can’t change it, because it is a constant. if you look to the right column in the playground it shows the value of myNumber.

frame04shot

Lets add another constant type this:

//same thinglet
myOtherNumber = 2

Now we made another constant with the value 2. Again to the right is the value of the number.

Besides let there is also var, which makes a variable. A variable is an identifier which can change values. So let’s type:

//variable
var myResult =  0

The result is 0. Once you have assigned an identifier with var or let, you use the Identifier without them.

If we wanted to add two numbers together we could do this:

myResult = 4 + 4

The result shows up as 8. Every time you assign a value to myResult it changes to that value. You can also use identifiers here. for example:

myResult = myOtherNumber + 4

The result shows up as 6. When you assign some value to myResult it change to that number. You can also use identifiers here. For example, type this:

myResult =  4 + myOtherNumber

You’ll notice the little drop-down box that appears as you type. This tells you identifiers and keywords that Xcode knows. These are auto-completion shortcuts to typing

kinderSwift 3 auto-complete

You can use your arrow keys then the tab keys to select the value. If there is only one value you just hit tab. You can also use your mouse to click on them. You can also keep typing. The choices will refine themselves. Press tab at any time.

You use variables just like constants. You can even use the variable you are assigning and assign it back to itself. For example, type this:

myResult = myResult + myNumber

This Shows us a result of 10. myResult was 6, and we added 4 more to it, then saved that value back into myResult.
That is how we use a variable. We assign it either literal values like number or we assign an expression to it like adding two numbers together. You cannot do this to a constant. try this:

myNumber = 4+4

You will get a little red error circle. The red circle means there is a mistake in the syntax of this line of the program. Click on the error and you will see the error message.

kinderSwift 3 let error

Xcode is telling you that anything assigned by let cannot be changed for the life of the application. You are stuck with it.
Change it to the variable myResult and the error goes away.

You will get an red error for misspelling an identifier. Make myResult myresult and see what happens. Swift like many computer languages is case sensitive. Be sure you name things correctly.
That’s it for this lesson, Next we’ll go on to doing a little more math.

The Whole Code

//This is a comment
let myNumber = 4
//Same Thing
let myOtherNumber = 2
//variable
var myResult = 0
myResult = 4 + 4
myResult = myOtherNumber + 4
myResult = myNumber + myOtherNumber
myResult = myResult + myNumber
myResult = 4 + 4

Swift Swift: Formatting a UIPickerView

[Updated to Swift 2.0/iOS9.0 9/15/15]

I’ve posted on UIPickerViews before, but in the comments for that post, I got a question that needed an answer so big, it was worth a new post.

UIPickerViews are those spinning wheel slot machine type controls. For a variety of reasons I went into in the earlier post they are not as common as other  controls in iOS. The reason I’ll focus on here is the lack of properties for a UIPickerView. It relies heavily on delegates. In this lesson we’ll look at some of those delegate methods.

Setting Up a Demo

I debated just having people go to the UIPickerView lesson, and start with that, but decided it would be simpler to start with a single-component picker view instead of the double component in that lesson. I will go through the setup quickly and if you  are not understanding something, I’d suggest clicking here and doing that lesson first.

Make a new project with Command-Shift-N, under iOS make a single view project named SwiftUIPickerFormatted. Drag a label and a picker view onto the view controller on the storyboard.
Screenshot 2014-10-20 12.11.21

Open the Assistant editor, and control-drag from the label to make an outlet named myLabel. Control-drag from the picker view and make an outlet named myPicker. Close the assistant editor and go to the ViewController.swift file. Clean up the code, then add the data for the picker view there so it looks like this:

class ViewController: UIViewController {

    @IBOutlet weak var myPicker: UIPickerView!
    @IBOutlet weak var myLabel: UILabel!
    let pickerData = ["Mozzarella","Gorgonzola","Provolone","Brie","Maytag Blue","Sharp Cheddar","Monterrey Jack","Stilton","Gouda","Goat Cheese", "Asiago"]
    override func viewDidLoad() {
        super.viewDidLoad()
        myPicker.dataSource = self
        myPicker.delegate = self
    }

}

UIPickerView needs a delegate and a data source.  In the viewDidLoad above we set both the delegate and dataSource to to self so we can add the required methods here. Change the class declaration to this:

class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {

You will get the classic

Type 'ViewController' does not conform to protocol 'UIPickerViewDataSource'

error.  Xcode is whining at you to add some required methods for the protocol. The two methods are in the data source. Add these towards the bottom of your code:

//MARK: - Delegates and data sources
    //MARK: Data Sources
    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerData.count
    }

We have only one component for the picker view so we return a literal 1. Using .count we get the number of rows from the data. We have some optional methods to use in UIPickerViewDelegate. Add these below the Data Source methods:

 //MARK: Delegates
    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickerData[row]
    }

    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        myLabel.text = pickerData[row]
    }

The first method places the data into the picker and the second selects and displays it in the label. You can now build and run and spin the wheel a bit:
Screenshot 2014-10-21 07.38.20

Formatting Picker Views with Attributed Strings

Now that we have set up a picker view, we might want a different font or color. There is a method which uses attributed strings.  Add this under the code we already have:


    func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
        let titleData = pickerData[row]
        let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 15.0)!,NSForegroundColorAttributeName:UIColor.blueColor()])
        return myTitle
    }

If you are not familiar with attributed Strings,  click here and check out my earlier post on how to use them. This should change the font to blue 15 point Georgia given the attributed string we have. Build and run.
Screenshot 2014-10-21 07.39.05
We do get blue, but no font change. You can change many attributes of a string. You cannot change the font in  attributed text  for picker views.

Using UIViews to Format the Picker

There is one more very powerful method for displaying something on a UIPickerView. There is a method in the delegate to display a UIView. One subclass of UIView is a UILabel. So we could make a label and have the delegate method return a formatted UILabel. Add this example using attributed strings to the code we have so far:

    func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
        let pickerLabel = UILabel()
        let titleData = pickerData[row]
        let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 26.0)!,NSForegroundColorAttributeName:UIColor.blackColor()])
        pickerLabel.attributedText = myTitle
       return pickerLabel
    }

Build and run.

Screenshot 2014-10-21 07.40.24

We get a change of font, but it is left justified. I went back to a black font for our next addition. With a UILabel in this delegate method, you can use all the properties of a UILabel instead of attributed text. I could use text and font property instead of attributed text. I’ll change textAlignment to .Center and I’ll add a colored background to the label by adding this to the delegate method.

         //color  and center the label's background
        let hue = CGFloat(row)/CGFloat(pickerData.count)
        pickerLabel.backgroundColor = UIColor(hue: hue, saturation: 1.0, brightness:1.0, alpha: 1.0)
        pickerLabel.textAlignment = .Center
        return pickerLabel

As I discussed in my color post on hues, this is a simple example to do multiple colors. Line two takes the current element and divides it by the number of elements in our array. Since both are type Int, I cast them to CGFloat before I do the division. This will be a  CGFloat between 0 and 1, which I use as my hue in assigning a color. Build and run:
Screenshot 2014-10-21 07.41.19

You should be a bit more conservative with memory using this. A better way to write this is:

func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
        var pickerLabel = view as! UILabel!
        if view == nil {  //if no label there yet
            pickerLabel = UILabel()
            //color the label's background
            let hue = CGFloat(row)/CGFloat(pickerData.count)
            pickerLabel.backgroundColor = UIColor(hue: hue, saturation: 1.0, brightness: 1.0, alpha: 1.0)
        }
        let titleData = pickerData[row]
        let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 26.0)!,NSForegroundColorAttributeName:UIColor.blackColor()])
        pickerLabel!.attributedText = myTitle
        pickerLabel!.textAlignment = .Center
        return pickerLabel

    }

This way we check if the label is already created before creating a new one.

Sizing the UIPickerView

You’ll notice that things seem a little squeezed in using the label. One way of fixing this is two more delegate methods: rowHeightForComponent and widthForComponent. Add this to increase the spacing between cells in the picker view:

 func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 36.0
    }

If you build and run, you get this:

Screenshot 2014-10-21 07.42.04

While in a single component, it is not so important, if you have multiple components you can change the width of each spinner as well. Let’s make the component smaller. Add this code:

 func pickerView(pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        return 200
    }

We are making all the components the same here, since we only have one. We could use the component parameter to identify the component and have different lengths for each one. Build and run.

Screenshot 2014-10-21 07.43.00

That is a few of the things you could do with a UIPickerView. There are a lot more, and since it accepts a UIView anything is possible for a user interface. Apple does recommend in the Human Interface Guide that UITableViews are a better option if you want to get complex. But the UIPickerView does have some very good uses, limited by your creativity.

The Whole Code

//
//  ViewController.swift
//  SwiftUIPickerFormatted
//
//  Created by Steven Lipton on 10/20/14.
//  Copyright (c) 2014 MakeAppPie.Com. All rights reserved.
//  Updated to Swift 2.0  9/15/15 SJL

import UIKit

class ViewController: UIViewController,UIPickerViewDataSource,UIPickerViewDelegate {
    
    @IBOutlet weak var myPicker: UIPickerView!
    @IBOutlet weak var myLabel: UILabel!
    let pickerData = ["Mozzarella","Gorgonzola","Provolone","Brie","Maytag Blue","Sharp Cheddar","Monterrey Jack","Stilton","Gouda","Goat Cheese", "Asiago"]
    override func viewDidLoad() {
        super.viewDidLoad()
        myPicker.delegate = self
        myPicker.dataSource = self
        
    }
    //MARK: - Delegates and data sources
    //MARK: Data Sources
    func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        return 1
    }
    func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return pickerData.count
    }
    //MARK: Delegates
    func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return pickerData[row]
    }
    
    func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        myLabel.text = pickerData[row]
    }
    
    func pickerView(pickerView: UIPickerView, attributedTitleForRow row: Int, forComponent component: Int) -> NSAttributedString? {
        let titleData = pickerData[row]
        let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 26.0)!,NSForegroundColorAttributeName:UIColor.blueColor()])
        return myTitle
    }
 /* less conservative memory version
    func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
        let pickerLabel = UILabel()
        let titleData = pickerData[row]
        let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 26.0)!,NSForegroundColorAttributeName:UIColor.blackColor()])
        pickerLabel.attributedText = myTitle
        //color  and center the label's background
        let hue = CGFloat(row)/CGFloat(pickerData.count)
        pickerLabel.backgroundColor = UIColor(hue: hue, saturation: 1.0, brightness:1.0, alpha: 1.0)
        pickerLabel.textAlignment = .Center
        return pickerLabel
    }
  */
    
/* better memory management version */
    func pickerView(pickerView: UIPickerView, viewForRow row: Int, forComponent component: Int, reusingView view: UIView?) -> UIView {
        var pickerLabel = view as! UILabel!
        if view == nil {  //if no label there yet
            pickerLabel = UILabel()
            //color the label's background
            let hue = CGFloat(row)/CGFloat(pickerData.count)
            pickerLabel.backgroundColor = UIColor(hue: hue, saturation: 1.0, brightness: 1.0, alpha: 1.0)
        }
        let titleData = pickerData[row]
        let myTitle = NSAttributedString(string: titleData, attributes: [NSFontAttributeName:UIFont(name: "Georgia", size: 26.0)!,NSForegroundColorAttributeName:UIColor.blackColor()])
        pickerLabel!.attributedText = myTitle
        pickerLabel!.textAlignment = .Center
        
        return pickerLabel
        
    }
    
    func pickerView(pickerView: UIPickerView, rowHeightForComponent component: Int) -> CGFloat {
        return 36.0
    }
    // for best use with multitasking , dont use a constant here.
    //this is for demonstration purposes only.
    func pickerView(pickerView: UIPickerView, widthForComponent component: Int) -> CGFloat {
        return 200
    }
    
    
    
}

Swift Swift: Using Attributed Strings in Swift

[Updated to Swift 2.0/iOS9  9/30/15 SJL]
Sometimes you want to be fancy with your strings. For most uses, a basic string works well. Normal strings have no character or paragraph formatting. They rely on the properties of the control to format them. The system only formats the full string, not parts of it. For formatting a part of a string, you need an attributed string which specifies parts of the string formatted in different ways. In this lesson we’ll learn how to work in attributed strings in Swift.

Set Up A Project

In Xcode open a new project with Command-Shift-N. Use an iOS Application of a Single View Template. Add one label and three buttons looking like this:
Screenshot 2014-10-19 06.59.09
Open the assistant editor, set to Automatic so the ViewController.swift file appears. Control-drag from the label to the code in the ViewController class. Make an outlet called myLabel. Drag from the ChalkDuster button to the code. Make an action named myFontButton. From the circle next to the code click-drag from the circle to the button named Georgia until the button highlights. Release the button, do the same from the code to the button titled AmericanTypewriter-Bold.
Close the assistant editor, and go over to the ViewController.swift file. Remove the didRecieveMemoryWarning method.
The class so far should look like this:

class ViewController: UIViewController {
    @IBOutlet weak var myLabel: UILabel!
    @IBAction func myFontButton(sender: UIButton) {
    }
    override func viewDidLoad() {
        super.viewDidLoad()

    }

Add the following two properties to the ViewController class:

var myString = "I Love Pizza!"
var myMutableString = NSMutableAttributedString()

We will need a string and attributed text string. I’m using a NSMutableAttributedString so I can add attributes as we go along in the lesson. If you have only one time you set attributes, you can do that with a NSAttributedString.

Initializing an Attributed String

in the viewDidLoad method, add the following code:

 myMutableString = NSMutableAttributedString(
    string: myString,
    attributes: [NSFontAttributeName:UIFont(
        name: "Georgia",
        size: 18.0)!])
//Add more attributes here

//Apply to the label
myLabel.attributedText = myMutableString

Line 1 initializes an attributed string with the string myString and an attribute dictionary. Here we used an attribute named NSFontAttributeName as the key, and a UIFont object as the value. Build and run. You will see this in the label:
Screenshot 2014-10-19 07.23.08

Some Things to do with Attributed Text

Once you make the attributed string you can change it as much as you want with the addAttribute method. There are a lot of attributes to change. For a list of them, you can look here in Apple’s documentation. I’ll go through a few useful ones for examples.

Add the following below the Add attributes here comment:

myMutableString.addAttribute(NSFontAttributeName,
    value: UIFont(
        name: "Chalkduster",
        size: 24.0)!,
    range: NSRange(
        location: 7,
        length: 5))

Just like the initializer, we use the NSFontAttributeName attribute as our attribute and 24 point Chalkduster as our font. What is new is range. An NSRange is a struct used for sequential data, such as strings. It has a location and a length. In the case above the location is 7 and the length 5. If you do the counting, this is the word Pizza in our original string. This will change the font of Pizza to 24 point Chalkduster. Build and run

Next add this line under the last one:

myMutableString.addAttribute(NSFontAttributeName,
    value: UIFont(
        name: "AmericanTypewriter-Bold",
        size: 18.0)!, 
    range: NSRange(
        location:2,
        length:4))

This time we change the font of the word Love to 18pt American Typewriter bold. Build and run:

Now add this under the previous two lines:

myMutableString.addAttribute(NSForegroundColorAttributeName,
    value: UIColor.redColor(), 
    range: NSRange(
        location:2,
        length:4))

We change the font color to red on the word Love with the NSForegroundColorAttributeName attribute . Build and run:

And now add these three lines under those:

myMutableString.addAttribute(NSFontAttributeName,
    value: UIFont(
        name: "Georgia",
        size: 36.0)!,
    range: NSRange(
        location: 0, 
        length: 1))
myMutableString.addAttribute(NSStrokeColorAttributeName,
    value: UIColor.blueColor(), 
    range:  NSRange(
        location: 0,
        length: 1))
myMutableString.addAttribute(NSStrokeWidthAttributeName,
    value: 2, 
    range: NSRange(
        location: 0,
        length: 1))

The first attribute we know already. We set 36pt Georgia to the word I. Line two using NSStrokeColorAttributeName sets the color for the outline of the letter I to blue. The third attribute uses NSStrokeWidthAttributeName to set a stroke width, giving us an outlined letter. Build and run this:

You can set the background as well, but be careful. Add this to the code under the last code:

let stringLength = NSString(string: myString).length
myMutableString.addAttribute(NSBackgroundColorAttributeName,
    value: UIColor.greenColor(),
    range: NSRange(
        location: 0, 
        length: stringLength))
myLabel.backgroundColor = UIColor.grayColor()

Our range this time will be the complete string. The first line gets the length of the string is a slightly odd way. String has no length property Where NSString does. The last line is for better contrast of what is going to happen. The NSBackgroundColorAttributeName attribute will change the background for the font to green, but it does not change the background for the view. Our label is gray, and our font background is green. Build and run:

The font background will be the height of the largest letter, and as long as the range specified. If the label is bigger than the text size, you will have two background colors.

Changing the Same Range

Nothing says you cannot change a range once you added it. Change the myFontButton to

 @IBAction func myFontButton(sender: UIButton) {
    myMutableString.addAttribute(NSFontAttributeName,
        value: UIFont(
            name: sender.titleLabel!.text!, 
            size: 24.0)!, 
        range: NSRange(
            location: 7,
            length: 5))
   myLabel.attributedText = myMutableString
    }

In this code we take the title of the button and use it as a font name for the word Pizza. Build and run. Tap the Georgia button,

tap the American Typewriter Bold Button

Tap the Chalkduster Button.

Screenshot 2014-10-19 07.42.28

This is just the start of what you can do with attributed text. In the next lesson we’ll apply it to more labels and the UIPickerView — Sort of.

The Whole Code

//
//  ViewController.swift
//  SwiftAttributedString
//
//  Created by Steven Lipton on 10/18/14.
//  Copyright (c) 2014 MakeAppPie.Com. All rights reserved.
//

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var myLabel: UILabel!
    @IBAction func myFontButton(sender: UIButton) {
        myMutableString.addAttribute(NSFontAttributeName,
            value: UIFont(
                name: sender.titleLabel!.text!,
                size: 24.0)!,
            range: NSRange(
                location: 7,
                length: 5))
        myLabel.attributedText = myMutableString
    }
    var myString = "I Love Pizza!"
   
    var myMutableString = NSMutableAttributedString()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Initialize the mutable string
        myMutableString = NSMutableAttributedString(
            string: myString,
            attributes: [NSFontAttributeName:
                UIFont(name: "Georgia", size: 18.0)!])
        
        //Add more attributes here:
        myMutableString.addAttribute(NSFontAttributeName,
            value: UIFont(
                name: "Chalkduster", 
                size: 24.0)!,
            range: NSRange(
                location: 7,
                length: 5))
        myMutableString.addAttribute(NSFontAttributeName,
            value: UIFont(
                name: "AmericanTypewriter-Bold",
                size: 18.0)!,
            range: NSRange(
                location:2,
                length:4))
        myMutableString.addAttribute(NSForegroundColorAttributeName,
            value: UIColor.redColor(),
            range: NSRange(
                location:2,
                length:4))
        
        myMutableString.addAttribute(NSFontAttributeName,
            value: UIFont(
                name: "Georgia", 
                size: 36.0)!,
            range: NSRange(
                location: 0, 
                length: 1))
        myMutableString.addAttribute(NSStrokeColorAttributeName,
            value: UIColor.blueColor(),
            range:  NSRange(
                location: 0, 
                length: 1))
        myMutableString.addAttribute(NSStrokeWidthAttributeName,
            value: 2,
            range: NSRange(
                location: 0, 
                length: 1))
        let stringLength = NSString(string: myString).length
        myMutableString.addAttribute(NSBackgroundColorAttributeName,
            value: UIColor.greenColor(),
            range: NSRange(
                location: 0, 
                length: stringLength ))
        myLabel.backgroundColor = UIColor.grayColor()
        
        //Apply to the label
        myLabel.attributedText = myMutableString
    }

}