SwiftUI Basic Tutorial

SwiftUI only supports Xcode 11, iOS 13 or later versions.

The official document links: developer.apple.com/tutorials/s…

Creating a composite view

This article will guide SwiftUI development through a Landmarks example (an App that can discover and share your favorite locations). We will use the SwiftUI framework to build the Landmark details interface.

Landmarks made use of Stacks to combine images and text for view layout. You need to reference the MapKit framework header to create a map view. You can optimize your view layout with Xcode’s new real-time feedback feature.

1. Download the Demo project. 2. Download Xcode11 Beta.

Create a project

Use the SwiftUI application template to create your project, and then explore the SwiftUI canvas.

To experience Xcode 11’s Live view preview and interactive features, make sure your MAC version is macOS 10.15 Beta.

The first step

Open Xcode->Create a new Xcode project, or go to File > New > Project to Create the project.

The second step

In the Template selection area, select iOS->Single View App->Next.

The third step

Enter the project name Landmarks-> check Use SwiftUI->Next to save.

The fourth step

In the Xcode navigation bar, create ContentView.swift. Typically SwiftUI declares two structures. The first structure inherits from the View and lays out the View here. The second structure declares a Preview of a ContentView, inherited from the PreviewProvider.

Thanks @soolychristina gay friends for your helpful tips. This is not the concept of inheritance, the original description is as follows: The first structure conforms to The View protocol and describes The View’s content and layout. The second structure declares a preview for that view.

So the two structures declared here are more likely to follow the View and PreviewProvider protocols.


import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello World")
    }
}

struct ContentView_Preview: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Copy the code

Step 5

Click Resume on the SwiftUI Canvas to preview the view.

Tip: If the Canvas is not displayed, go to Editor > Editor and Canvas to display it.

Step 6

Change Hello World to Hello SwiftUI!

SwiftUI automatically updates the view when you modify the copy. (It’s just hot-reload.)

Custom Text View

You can customize a TextView in two ways. The first way is to modify the view code directly, and the second way is to use the Inspector to help you code.

When you build Landmarks, you can use any editor to do the coding: directly modify the source code, through the canvas, through the Inspector View. The code doesn’t care what tools you use, it’s always up to date.

Next, you will customize the Text View through Inspector

The first step

On the Preview canvas, hold down the Command key + click on the Text box and the Inspector will be evoked.

The inspector popup displays different properties for different UI controls.

The second step

Modify the properties of the Text Text box using the Inspector.

The third step

Modify the text box font.

Modify the text box font to take advantage of the system font.

The fourth step

Manually modify the code by adding.color(.green) to change the text to green. To customize SwiftUI views, you can call modiFIERS. Modifiers can modify the attributes of a view, and the modifier returns a new view, so often multiple Modifiers are stacked vertically on top of each other like a chain. (In plain English, chained programming returns itself every time a method is called).


import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Turtle Rock")
            .font(.title)
            .color(.green)
    }
}

struct ContentView_Preview: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Copy the code

The code you write must correspond to the view one to one. When you modify the View properties with Inspector, Xcode automatically updates your code.

Step 5

At this point, open inspector, and change the text Color property to Inherited.

Step 6

One thing to note is that Xcode automatically updates your code based on inspector changes.

Stack views with Stacks

We created a text box to display landmark details and placed the text control in the header. When we create the SwiftUI View control, we put the content, layout, and behavior of the control in the body property; However, the body property only returns a view. Stacks can be used to stack multiple Views vertically, horizontally, etc.

In this section, we’ll use a vertical stack to display park details.

The first step

Command+ press text to initialize the method area. Select Embed in VStack.

The second step

Next, we’ll drag and drop a Text View onto the stack.

Click the + sign to open the Library panel. Drag and drop a Text View behind Turtle Rock.

The third step

Modify text View text to Joshua Tree National Park.

The fourth step

Set the font for the Text View.


import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack {
            Text("Turtle Rock")
                .font(.title)
            Text("Joshua Tree National Park")
                .font(.subheadline)
        }
    }
}

struct ContentView_Preview: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Copy the code

Step 5

Example Change the VStack alignment.


import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("Turtle Rock")
                .font(.title)
            Text("Joshua Tree National Park")
                .font(.subheadline)
        }
    }
}

struct ContentView_Preview: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Copy the code

If the alignment is not set, the VStack defaults to vertically centered content.

Step 6

In the panel, Command+ click Joshua Tree National Park to evoke Inspector and select Embed in HStack.

Step 7

Add a new text box after Location, modify the text box text, and set the font.


import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("Turtle Rock")
                .font(.title)
            HStack {
                Text("Joshua Tree National Park")
                    .font(.subheadline)
                Text("California")
                    .font(.subheadline)
            }
        }
    }
}

struct ContentView_Preview: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Copy the code

Step 8

You can add Space between two horizontal text boxes to fit the width. Space fills the superview either horizontally or vertically.


import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("Turtle Rock")
                .font(.title)
            HStack {
                Text("Joshua Tree National Park")
                    .font(.subheadline)
                Spacer()
                Text("California")
                    .font(.subheadline)
            }
        }
    }
}

struct ContentView_Preview: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Copy the code

Step 9

Finally, use the padding() to set the margin.


import SwiftUI

struct ContentView: View {
    var body: some View {
        VStack(alignment: .leading) {
            Text("Turtle Rock")
                .font(.title)
            HStack {
                Text("Joshua Tree National Park")
                    .font(.subheadline)
                Spacer()
                Text("California")
                    .font(.subheadline)
            }
        }
        .padding()
    }
}

struct ContentView_Preview: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Copy the code

Create a custom picture view

Now that we have a view of the park name and location, we will add an image to the park.

You don’t need to add a lot of code to add a mask, border, shadow image.

The first step

Add an image to the Asset Catalog.

Find the Turtlerock. PNG image in the Resource folder and drag it to the Asset Catalog.

The second step

Select File > New > File to open the template selection panel. In the User Interface area, select SwiftUI View->Next and name it circleImage.swift.

The third step

Replace the Text build method with Image.

import SwiftUI

struct CircleImage: View {
    var body: some View {
        Image("turtlerock")
    }
}

struct CircleImage_Preview: PreviewProvider {
    static var previews: some View {
        CircleImage()
    }
}
Copy the code

The fourth step

Call the.clipShape(Circle()) method to create a circular view.

Step 5

Create another circle and fill it with grey. And make it the border of the image.


import SwiftUI

struct CircleImage: View {
    var body: some View {
        Image("turtlerock")
            .clipShape(Circle())
            .overlay(
                Circle().stroke(Color.gray, lineWidth: 4))
    }
}

struct CircleImage_Preview: PreviewProvider {
    static var previews: some View {
        CircleImage()
    }
}
Copy the code

Step 6

Add shadows.

Step 7

Change the border color to white.

import SwiftUI

struct CircleImage: View {
    var body: some View {
        Image("turtlerock")
            .clipShape(Circle())
            .overlay(
                Circle().stroke(Color.white, lineWidth: 4))
            .shadow(radius: 10)
    }
}

struct CircleImage_Preview: PreviewProvider {
    static var previews: some View {
        CircleImage()
    }
}
Copy the code

UIKit and SwiftUI mix

Now we need to create a map view. You can use the MKMapView class in MapKit to show the render map interface.

To use UIView or its subclasses in SwiftUI, you need to make your View comply with the UIViewRepresentable protocol. SwiftUI also announced a similar agreement with WatchKit and AppKit.

The first step

Create a new SwiftUI View to display MKMapView. File > New > File and then create mapView.swift.

The second step

Introduce a MapKit header file, and make the MapView comply with the UIViewRepresentable protocol.

The third step

The UIViewRepresentable protocol has two protocol methods to implement. The first is UIView(context:) to create MKMapView. The second updateUIView(_:context:) updates the view.

I’m going to dry out the body property, and then UIView(context:) protocol method to create MKMapView.


import SwiftUI
import MapKit

struct MapView: UIViewRepresentable {
    func makeUIView(context: Context) -> MKMapView {
        MKMapView(frame: .zero)
    }
}

struct MapView_Preview: PreviewProvider {
    static var previews: some View {
        MapView()
    }
}
Copy the code

The fourth step

Implement updateUIView(_:context:) protocol method to update the view (set the map latitude and longitude, etc.).

func updateUIView(_ view: MKMapView, context: Context) {
        letCoordinate = CLLocationCoordinate2D(latitude: 34.011286, longitude: -116.166868)letSpan = mkcoordinate espan (latitudeDelta: 2.0, longitude udedelta: 2.0)let region = MKCoordinateRegion(center: coordinate, span: span)
        view.setRegion(region, animated: true)}Copy the code

Step 5

When previewed in static mode, Xcode can only render SwiftUI view controls. Because MKMapView is a UIView subclass, you need to switch mode to Live mode to preview properly.

Click Live Preview to switch the Preview mode.

Combine the above child controls into a finished detail interface

We now have all the child control definitions implemented. Using our existing tools, we can combine these child controls to form a complete Landmarks detail interface.

The first step

In the project navigation area, select the contentView.swift file.

The second step

A VStack view is embedded outside the three Text View controls.

struct ContentView: View {
    var body: some View {
        VStack {
            VStack(alignment: .leading) {
                Text("Turtle Rock")
                    .font(.title)
                HStack(alignment: .top) {
                    Text("Joshua Tree National Park")
                        .font(.subheadline)
                    Spacer()
                    Text("California")
                        .font(.subheadline)
                }
            }
            .padding()
        }
    }
}
Copy the code

The third step

Place your custom MapView on top of the stack. Set the frame of the MapView. If you only set the height of the Mapview, the Mapview will automatically set its width to fit the parent view. So the MapView will fill the width area.


struct ContentView: View {
    var body: some View {
        VStack {
            MapView()
                .frame(height: 300)

            VStack(alignment: .leading) {
                Text("Turtle Rock")
                    .font(.title)
                HStack(alignment: .top) {
                    Text("Joshua Tree National Park")
                        .font(.subheadline)
                    Spacer()
                    Text("California")
                        .font(.subheadline)
                }
            }
            .padding()
        }
    }
}
Copy the code

The fourth step

Click Live Preview to get a Preview. In the Preview state, you can continue to code the view, and Live Preview updates the view in real time.

Step 5

Add the CircleImage to the stack.

struct ContentView: View {
    var body: some View {
        VStack {
            MapView()
                .frame(height: 300)

            CircleImage()

            VStack(alignment: .leading) {
                Text("Turtle Rock")
                    .font(.title)
                HStack(alignment: .top) {
                    Text("Joshua Tree National Park")
                        .font(.subheadline)
                    Spacer()
                    Text("California")
                        .font(.subheadline)
                }
            }
            .padding()
        }
    }
}
Copy the code

Step 6

Adjust the offset of Image.

Step 7

Add spacer placeholders at the bottom of the VStack.

Step 8

Finally, set edgesIgnoringSafeArea(.top).