Make Swift Playgrounds Apps: HStack, VStack and Layout

Transcript

We’ve learned some basics of Swift and some fundamental SwiftUI objects. Unfortunately what we’ve done as a demo doesn’t look so nice. So let’s get together the beginnings of a fun app to order pizza!

I’ll start by closing our current app.

Then I’ll make a new app. I’ll  pop out for a second and rename it Huli Pizza Takeout. I’ll make the accent color green this time. 

Inside the app I’ll change the name as we did before to Huli Pizza Takeout

Go to content view, and cut the Text, then paste it on top of the image. 

Change the code to this: 

VStack {
    Text("Huli Pizza Company")
       .font(.largeTitle).bold()
    Image(systemName:"rectangle.fill")
        .imageScale(.large)
        .font(.largeTitle)
}

And we get a different looking app. We have yet to talk about the keyword VStack

VStack is a special object that take code as its parameter. We call these closures. You denote a closure by a code block made of at least  a set of curly brackets. You’ll find code blocks in many places in Swift. The code block of  VStack appears in order Swift UI Views to be displayed vertically. Here we display text then an image, in this case a rectangle. 

Add another View to the stack  

Divider()

Dividers make lines. We’ve seen Spacer before. Spacers has a role of pushing all content in a direction. They fill up all available space. If I put a Spacer at the end of the code block 

Spacer()

It pushes everything to the top. 

We can change the background color of the stack with this modifier added after the code block. 

.background(Color.accentcolor)

There’s another common stack you can use for horizontal arrangement. The HStack arranges views horizontally. As stacks are themselves Views you can have stacks inside their stacks. For example,  below the Divider add this

HStack{
                Image(systemName: "circle.fill")
                Text("menuItem").font(.title)      
            }
            

I have the image and text in stack going from a leading edge to a trailing one. Notice I did not say left to right, because that can change with some languages such as Arabic and Hebrew

Add a Spacer to align to the left. 

Spacer()

You can nest these a deep as you want. I’ll add another VStack to add a description under the Menu Item, so I’ll encompass the Menu Description in the code block. 

VStack(){
    Text("menuItem").font(.title)
    Text("menu Description")
}

This is still centered. I’d have to use more spacer to get it left aligned. Fortunately HStack and VStack have alignment parameters for the alignment at right angles to their direction. For VStack, that means I can align to the leading edge. 

VStack(alignment:.leading){

This is looking good. We’ve built a wireframe for our app. Wire frames are common in app development, where developers use place markers like circles rectangles and a few place marker words to develop the look without worrying about the content.  

There’s usually more than one menu Iten on a menu though, and in our next lesson, we’ll look at a way we can get more Menu Items on to our app. 

The Whole Code

import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Huli Pizza Company")
                .font(.largeTitle).bold()
            Image(systemName: "rectangle.fill")
                .imageScale(.large)
                .font(.largeTitle)
                .foregroundColor(Color.black)
            Divider()
            HStack{
                Image(systemName: "circle.fill")
                VStack(alignment:.leading){
                    Text("Menu Item")
                    Text("Menu Description")
                }
                Spacer()
            }
            Spacer()
        }
        .background(Color.green)
    }
}

Run Real Apps with Swift Playgrounds for Mac 4.1

A quick review of the changes in Swift Playgrounds 4.1 on the Mac. Learn how you can make and publish an app without Xcode either directly to your Applications folder or to the app store.

Transcript

Apple’s release of Swift Playgrounds 4.1 for macOS might not look like a big change but it is huge. Here’s several thing you can do Straight from playgrounds on a Mac. 

 You can start an app by clicking the button in the lower left. 

You can see your existing  SwiftUI Code on a Mac from files created on iPad. I’ll open the Play4_1 HuliPizza app file and it loads easily, with the Preview working perfectly. 

In 4.1 with macOS 12.4, you can run this directly on the Mac. Drop down menus are functional. 

Stop the app and go to the app setting.  

Capabilities set you up for a variety of device frameworks including files, cameras and internet access, with some specifically for macOS. 

Next you’ll find Team and bundle identifiers if you are a registered App developer.  If you plan to send your app to the app store, set these few settings, and you are ready. You can set you team and bundle here.  Categories and version numbers are set here too. 

Unlike Xcode, If you got all that done, Click the button on the bottom to send your app to app store connect fo posting in the app store. 

Exclusive to macOS version of playgrounds, clicking the button above it installs the playground as an app to your applications folder.  Click on applications and you’ll find it there.

  If you are building in-house Mac apps, there’s nothing easer to get you apps running without Xcode, a developer license or the app store. 

The new format for SwiftUI playground apps is also portable to Xcode.  Just open the file in Xcode and you are ready to go. 

If you are working in swift UI, Or start your app with swiftUI you can a simple lightweight IDE on almost any mac without the heavy overhead of Xcode. Playgounds doesn’t replace Xcove, but if you need to get work done on interfaces , wireframes or prototypes, this is one option you should really consider.  See al this in action in the video above.

Make Swift Playgrounds Apps: Using Functions

Transcript

We have Identifiers for values we can use  repeatedly.  If you think of  constants as nouns we’ll need some verbs to do actions. Swift has actions we can use repeatedly. 

We call these  functions. Here’s a simple example. Add this to your code just below the thing2 declaration.  

let myMax = "\(max(thing,thing2))"

This is a function. A function is a set of code stored somewhere that does something you want done. In this case, the max function finds which number of two numbers is bigger.  

Functions require values to work correctly. You’ll find two ways function obtain values. The max function has in parentheses thing and thing2, We call stuff in the parentheses parameters.  

We’ll make the result on the bottom of our output. Add this to our code. 

Text(myMax)

We’ll see in preview that we get our answer of 11. Text also had parentheses – is Text also a function?

Before I answer that question, let’s look at a string function first, and show you an example of the second and more common way you might use a function in Swift. Change the code to 

Text(myMax.appending(" is bigger"))

If you look at the preview, swift Added  is bigger to 11. In some computer languages, you’d see both myMax and ” is bigger” as parameters, much like max up above. However in object oriented languages, you’ll often find one parameter outside the parentheses , then a dot, and then the function with any parameter it needs. 

When a function takes this form we call it a method. Methods are functions that require a special data type to run. Identifiers assigned to a data type are called objectsmyMax is an object of the String type, and appending is a method of String. Types in swift are usually capitalized. 

So if you go back to Text, is it an object or a type?  Text is a type defined by our user interface framework called SwiftUI. All types have a hidden method called init. The init method sets up a new object of a Type. So our code really reads.

Text.init(myMax.appending(" is bigger")) 

A Text object with the results of  myMax and  ” is bigger “ gets created then used immediately. 

There’s another object called Spacer, which makes variable spacing. If I place it under the code we have I can move everything to the top.  Using Init I’d write it like this. 

Spacer.init()

Because there would be Init everywhere,  in Swift and SwiftUI, we hide init by specifying a type and the parameters of initSpacer had no parameter but you always have to show the parentheses so I get. 

Spacer()

If I hide init.

Apple created a framework called SwiftUI to create user interfaces for your applications in Swift. We’ve been writing in SwiftUI code. Text, Image, VStack, and Spacer are all SwiftUI code. SwftUI has special function it adds to object called modifiers.  You see some modifiers on the Image Object such as imageScale, and foreground color.  There’s also a modifier called bold which works on text.  Add that to our text. 

Text(myMax.appending(" is bigger")).bold()

The text changes to bold. Modifiers change the properties of the object.There is also a font modifier.  I’ll make Hello Pizza use a large title and bold. 

Text("Hello, Pizza!").font(.largeTitle).bold()

And we have a bigger font in bold. 

I’ll change the Image too to use a title font. 

Image(systemName: "\(thing).square")
    .imageScale(.large)
    .foregroundColor(.accentColor)
    .font(.title)

The foregroundColor change the color of text and Sf Symbols. I’ll make it red. Notice this has some predefined values. We can select one of these fro easy color choices. 

Image(systemName: "\(thing).square")
    .imageScale(.large)
    .foregroundColor(.red)
    .font(.title)

            With a few functions, methods and modifiers we’ve changed the look of our app quite a lot. We’ll make some more changes next time as we add some more objects and  Learn to arrange the SwiftUI Objects we have. 

The Whole Code

import SwiftUI

struct ContentView: View {
    let thing = 5 + 3 * 2
    var body: some View {
        let thing2 = thing + 5
        let myMax = "\(max(thing, thing2))"
        VStack {
            Text("Hello, Pizza!").font(.largeTitle).bold()
            Image(systemName: "\(thing).square")
                .imageScale(.large)
                .foregroundColor(.red)
                .font(.title)
            Text("Hello, \(thing2)!")
            Text(myMax.appending(" is bigger")).bold()
            Spacer()
        }
    }
}

Make Playgrounds Apps: Constants and Calculations

Transcript

We’ve got an application started, but it is very hard to change to do anything with.  If I wanted something other than guitars, such as a lightbulb or tv, I’d have to change the entire program. 

Swift playgrounds and its bigger brother on the Mac, Xcode,  have special programs called compilers and interpreters. These take our typed words and make them readable by the chips inside your iPad or Mac. There languages use interpreters too, such as Javascript in your web browser. 

Swift and most programming languages have a way for developers to tell the  that there is a name for a value. We call this a constant. IN swift we assign it  like this above 

let thing = "guitars`

The let is a keyword, a special word that tells Swift that what follows is an assignment of a constant. The word thing is an identifier, a name for a value, which I put after an equals sign.  It can be any word, but we usually leave the first letter lowercase to tell us it is an identifier.

Once you define an indetifier, you can use it. Fro example I can change the Image to this:

Image(systemName: thing)

And we see out guitars

 I can’t put a constant like thing directly into a string, I can however tell the compiler this is a value with interpolation characters of backslash and parentheses like this; 

Text("Hello, \(thing)")

I can change the value of thing, and everything that uses it changes. For example I’ll make it 

let thing = "tv"

And I see tv’s. Or a lightbulb 

let thing = "lightbulb"

And we get lightbulbs.

I’m not limited to strings. I’ll change thing to 5

let thing = 5

And I get an error. If I. Look at the error, it is the compiler whining that Image doesn’t understand integer numbers, only strings.  I can fix that with interpolation, 

`Image(systemName: “\(thing)”)`

And now it works, but is blank. The text shows correctly though. There is no sf symbol named 5 so it is blank. But there is the number 0 through 50   with .square or .circle after it.  So I can change the string to 

Image(systemName: "\(thing).square")

And it works. 

Once you start working with numbers, you can also start working with math. There are four operators you can use  with numbers. The first is addition

let thing = 5 + 3

THIng now equals 8, and we see that in the preview. Subtraction is with a minus sign

let thing = 5 - 3

Which assigns 2, and we see that in the preview too. Division is a forward slash

let thing = 5 / 3

And this gets us a result you might not expect of 1. The numbers we are using are Integers, numbers without fractions, so the result is an integer value.  But there some left over from one and the remainder  operators can show us that

let thing = 5 % 3

Which is two.  IF you really want the fractional value, use a decimal point after the value. 

let thing = 5.0 / 3.0

You’ll see the value but notice we have no symbol. There are only SF symbols for the integer 0 through 50. 

You are not limited to only one operator I’ll change this to 

let thing = 5 * 3 – 1

I get 14. Multiplication and division are calculated before addition and subtraction. 

When a constant is a number you can do math to it, since it represents a number. For example I can do this

Image(systemName: "\(thing + thing ).circle")

I’ve added thing to itself.  I can also make another constant from thing, but you have tone careful. I’ll make a thing2 under thing

let thing2 = thing + 2

And I get an error message.  Cut and paste this Above Vatack, and the error message gets away.  Constant declarations must be in specific places. I’ll discuss why in a later video after we have a few more concepts down. 

Meanwhile we have a new error message which says  thing2 is lonely because no one is using it. I’ll assign it to my text. 

Text("Hello, \(thing2)")

And we get  a response on the preview. 

You’ve covered some more basics of assignment and some of the math functions you can use with integers.  Next time, I’ll show you some more sophisticated  stuff you can do with numbers and strings called functions. 

The Whole Code

if you want to look at everything we’ve done or copy and paste into playgrounds, here’s all the code we’ve used so far.

import SwiftUI

struct ContentView: View {
    let thing = 5 + 3 * 2
    var body: some View {
        let thing2 = thing + 5
        VStack {
            Text("Hello, Pizza!")
            Image(systemName: "\(thing - 1).square")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, \(thing2)!")
        }
    }
}

Make Playgrounds Apps: First Steps the video

Here’s the video version of the post from last week, Starting this week the video will post with text.

Make Swift Playgrounds 4 Apps: First Steps

Swift Playgrounds 4 changes the game if you want to get into programming on the iOS and iPadOS platforms. Today we start a series that takes you from knowing nothing about programming to writing apps, one step at a time. We’ll use the Swift programming language and the SwiftUI Framework for user interfaces. Along the way we’ll introduce plenty of programming concepts you can transfer to learning other programming languages.

What you’ll Need

All you need is Swift Playgrounds 4. You don’t need any experience programming. However, Swift playgrounds 4 as of this writing has a few requirements of its own. The app only runs on iPads with iOS 15, but I’d suggest 15.4 or later for best results.

You can get the app in the App Store for free.

Swift playgrounds can use the on-screen keyboard, but if you have one, I do suggest using a external keyboard for faster workflow. Usually I’ll be working on a iPad Pro with Magic Keyboard. which will give you more clarity in seeing the code.

As we go through the series, I’ll show you how to use the on-screen keyboard in case you don’t have an external keyboard including some cool tricks for editing. In this first lesson we’ll be using that on-screen keyboard.

First Steps

With Playgrounds installed on your iPad, now. Let’s get your first app running.

Open the playgrounds app. On the bottom you’ll see More Playgrounds.

The first two choices there are App and playground.  We’ll be using the app for our purposes. Tap app. 

At the top of the screen, you’ll get an icon with the name My App. Tap on My App, and you are in the app’s code. At the upper left is a button that says app settings. If you don’t, tap the sidebar button to show it.

Tap that. That sets the appearance of your app in the browser.  Tap name and change it to Hello Pizza. Under placeholder choose, the binoculars, and a blue color accent. 

Tap done and you see in the corner you new icon.

Now to add some code.  Tap the ContentView tab at the top. For many of these lessons we’ll do our work here.  Tap the sidebar button to hide it. 

We’ll discuss all of this code as we go through the series, but for now I want to point you to line 9. Text is a function, a command that tells the iPad to do something. In this case, Text tells the iPad to display the phrase Hello World!. Text will display anything found within those quote marks. Quote marks and the characters it contains are called a string. You can change the string by typing in the quotes. Tap after the d to get a cursor. Change to

Text(“Hello, guitars!”)

You’ll notice the preview on the right change to our new message.

Try typing in another phrase. I’ll put this on the top. Tap after the curly brace for VStack{ press return for a new line and add Tex with the onscreen keyboard. You get two changes:

First, you get the red X with a message. This is a syntax error. It means Swift does not understand what you are trying to say. As you type , you’ll often see this. It should go away after you finish, but if it does not, it means you made a mistake.

The second part is the autocomplete. Playgrounds guesses what you want to type, and give you suggestions. You tap on the correct one and Autocomplete will type for you. On top, autocomplete highlights the best guess Text. There is also on the left a return symbol. Pressing return adds that to your code. press return. Text gets added to your code.

Then add the rest of this

Text(“Hello, Pizza!”)

You’ll find the pizza phrase on top of the globe. 

Now let’s change the globe. We have an Image function here. Some functions have different ways of working, and when they do there will be parameters inside the parentheses. This one has a systemName parameter. systemName wants a string of a system image, what Apple calls an SF Symbol. If you tap the + and the Star at top, you’ll find a list of SF symbols.

Tap outside the list to dismiss it. I want guitars so change the system name to guitars

Image(systemName: "guitars")

The symbol changes to guitars

While it may not be the next video game sensation, you’ve modified the application to be your first program. Basically that’s all there is to programming, putting down statements containing functions like Image and Text to tell a user what to do. Of course there’s a lot of other statements and you will need to store data, make decisions and do the same same thing multiple times. In this series we’ll learn that and a lot more about user interaction.

Stay tuned to more fun next week as we learn about constants, some math, and adding strings together.

A Pro walkthrough of Swift Playgrounds 4

I’ll show you many of the new and nifty features of Swift Playgrounds 4 in this video.

Why You Don’t Draw a Straight Line to Success

When I start talking about drawing, most people usually say they can’t do art with the phrase “I can’t even draw a straight line.” Video 10 in the Explore art with Procreate series addresses this directly: I teach you to make the straight lines of the artist. However, in the video, I didn’t unpack what that phrase really means and why it is holding you back in a lot more than drawing.  

What do we mean by a straight line? Generally, we mean a line made with the aid of a ruler or computer. We are demanding a line that is accurate to a level only machines can do. It looks like this: 

It may be accurate, but an important feature of this line is how boring it is. It has no life or energy. the line is always the same, no matter who draws it.  What many people draw instead is this: 

It is the careful line of trying to imitate a machine. Even the slightest error is magnified in our brains, often leading to more errors. Perfectionism kills this line. The controlled line of handwriting often does not work as accurately as we wish. Controlling our fingers and wrist to make a line requires too many inputs for the long distance. Our bodies, therefore, cause us to send different inputs than someone else’s body, and this line is always unique in its mistakes. If it were accurate like the machine line, everyone’s handwriting would be the same. Our errors in lines are what make us individuals. It is part of identity, yet we curse ourselves for being unique by saying we can’t draw a straight line. That line should be celebrated, not cursed. 

I draw, like many artists, not with the fingers and wrist like we are handwriting, but with the arm. I make not one but several strokes, and somewhere in all of them is a straight line. 

This line might look like a messy scribble close up. If you make your marks small enough or use big enough paper,  it looks straight with lot more energy. 

This line is a series of attempts to make a successful straight line. Each attempt would not be considered a straight line as we defined the mechanical one. Put together. They make a line that works for most uses of straight. 

This technique is not only true of lines but most creative work. We expect our creative work to look machine-made when it is our humanity and unique perspectives and abilities that give it value. Even more, when we try not one but multiple failed lines until we get a straight line without a machine and with more energy and personality than that drab mechanical one. Only on close inspection do we see all the failures that went into making that line. 

The best, most artistic way to make a straight line is to try and fail as many times as possible. Somewhere in all that mess, what we are looking for appears. So too with life, success and all creative work. 

Custom Quick Help in Xcode

There are some powerful documentation features of Xcode you may not be using and will make your life a lot easier. Take a look at the downloaded exercise file. Go ahead and run it like I have here. I wrote a simple app to turn on and off a matrix of lights. Stop the app. 

Looking at the ContentView code, It is hard to figure out what is going on. Click On LightbankView.  I’ve got a light bank up top and a Toggle buttonView below it that I made. One’s a model and one is a view. I might use elsewhere they are hard to add to the code. 

Option-Click the VStack. You get a popup that describes how a VSstack works. If you open the right sidebar and click the Help icon you see the same info again. If you option-click LightBank, you get very little, but you can change this. You see under the quick help Declared in. You can click that and go to the definition. 

Above the definition, you’ll add a special comment. Instead of two slashes, add three. Add the comment. 

/// A data structure for a row of lights 

 Hit Command-B to build the project. Click on the LightBank struct and the quick help shows your summary. 

Any time you add three slashes and text above a declaration, it shows up in the Quick Help summary. In Xcode 11, You can do this faster with a command-click.  Command-click BankState, and select Add documentation. You get a place marker for your summary. Add the following: 

/// A pattern of lights.

 As this is an enum, I might want the possible values, so I’ll add that.

Can be .allOn, .allOff, .evenOn or .oddOn.

Really that should be in the discussion, not the summary. Press return before Can. The comment appears on the next line. Add a dash between the triple slash and Can. Build again and check the Quick Help. Both the sidebar and the popup show the values in the discussion section of the quick help. 

 /// - Can be .allOn, .allOff, .evenOn or .oddOn.

You can format this too. For using code case on my enum values, I’ll use the reverse single quote found above the tab key. I can quote my values like this: 

 /// - Can be `.allOn`, .`allOff`, `.evenOn` or `.oddOn`.

Build and check it out. 

There are other callouts besides discussion. Head down to the init. Command-click and Add documentation to init. For methods with parameters you also get the parameters already listed for you. You can add these manually or use the Add parameter in Command-Click.  Add these comments: 

/// A data structure for a row of lights
/// - Parameter count: The number of lights in a row
/// - Parameter on: The pattern of lights in the row from `BankState`

I like having enum values handy, so I’ll finish this off with a copy and paste of the line above. 

 /// - Can be `.allOn`, .`allOff`, `.evenOn` or `.oddOn`.

Build again and head back to ContentView

Option-Click LightBank. You get the summary for the Struct.

Option-Click on count and you get the quick help for the initializer.

Your summary even shows in the code completion. add this: 

var moreLights = Lightban

Code completion has a summary. 

You can do a lot more formatting and even links with markup in quick help. Markup is also used in Playgrounds. Check out chapter 4 of my Swift Playgrounds Application Development course for a lot more you can do with markup.  

The Whole Code

You can look at the completed code for this project on GitHub here:

Checklists in Swift UI

In our last tip, I made a single checkbox in SwiftUI. Let’s learn more about collections in SwiftUI and build a checklist. 

If you download the exercise file, you’ll find an expanded version of last week’s project. Under the model folder, I added some data for our list of pizzas to try.

let checkListData = [
     CheckListItem(title: "Neopolitan"),
     CheckListItem(title: "New York"),
     CheckListItem(title:"Hawaiian"),
     CheckListItem(title:"Chicago Deep Dish"),
     CheckListItem(title:"Californian")
 ]

You’ll see that has a struct backing it that stores the title and  an default value of false for each item. 

struct CheckListItem{
     var isChecked: Bool = false
     var title: String
 }

Suppose I wanted to make a list of all my items. Head to CheckListView.  I’d use a list like this: 

List(checkListData){ item in
     CheckView(isChecked: item.isChecked, title: item.title)
}
.font(.title)

However we get a message that CheckListItem does not conform to the Identifiable protocol.  Any object you iterate in Swift UI must have essentially a primary key, a unique identifier. I have two options here: The first is to use existing data, such as the title as my key. I can specify that by adding a parameter of id, set to my title.

 List(checkListData, id:\.title){ item in

The error disappears. However, that means I cannot have two titles the same. If you have unique data this works fine. You have to specify the id in this case, so this makes the checklist less adaptable. 

Our second and better possibility is to adopt the protocol Identifiable.  Head over to the ChecklistItem.  Add the Identifiable protocol to the struct. 

struct CheckListItem:Identifiable{ 

This protocol has one required property named id, which contains a unique identifier. While id can be any hashable type, I’ll make id an integer. 

var id: Int

I’ll change my data to include the id. I’ll add it to the first item. Then cut and paste into the rest. 

let checkListData = [
     CheckListItem(id:0,title: "Neopolitan"),
     CheckListItem(id:1,title: "New York"),
     CheckListItem(id:2,title:"Hawaiian"),
     CheckListItem(id:3,title:"Chicago Deep Dish"),
     CheckListItem(id:4,title:"Californian")
 ]

Our errors have disappeared. 

Change your content view to use the CheckList view. 

Again, I’ll Run on a device instead of the canvas.  You get a nice looking checklist that you can check. This is not yet storing the checkmarks. We’ll look into that in another tip. You’ll find it is best to adopt the Identifiable protocol for iterating in lists. 

The Whole Code

The code for this project is downloadable on GitHub at https://github.com/MakeAppPiePublishing/Tips_08_04_Checklist_End. There’s an accompanying video you can find at LinkedIn Learning.