Unsectioned

Preview this deck

Open library Shortcut (with Canvas)

Front

Star 0%
Star 0%
Star 0%
Star 0%
Star 0%

0.0

0 reviews

5
0
4
0
3
0
2
0
1
0

Active users

5

All-time users

6

Favorites

0

Last updated

4 years ago

Date created

Sep 25, 2020

Cards (45)

Unsectioned

(45 cards)

Open library Shortcut (with Canvas)

Front

⇧ + ⌘ + L

Back

Quickly open Shortcut

Front

⇧ + ⌘ + O

Back

Toggle Comments

Front

⌘ + /

Back

Show SwiftUI Inspector...(Code)

Front

⌃ + ⌥ + Click

 

Back

Group - Preview Provider

Front

You can use a Group to return multiple previews from a preview provider. Xcode renders the group’s child views as separate previews in the canvas.

A view’s children inherit the view’s contextual settings, such as preview configurations.

struct LandmarkRow_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            LandmarkRow(
            	landmark: landmarkData[0])
            LandmarkRow(
            	landmark: landmarkData[1])
        }
        .previewLayout(
        	.fixed(width: 300, height: 70))
    }
}
Back

Open library Shortcut (Without Canvas)

Front

⇧ + ⌘ + L

Back

Spacer()

Front

A spacer expands to make its containing view use all of the space of its parent view, instead of having its size defined only by its contents.

Back

Group

Front

Group is a container for grouping view content. Group creates several views to act as one, also to avoid Stack's 10 View maximum limit.

VStack {
    Group {
        Text("Hello")
        Text("Hello")
        Text("Hello")
    }
    Group {
        Text("Hello")
        Text("Hello")
    }
}
Back

To load icons from Apple’s SF Symbols set

Front

SwiftUI’s Image view lets us load any of the 2000+ icons from SF Symbols, with many of them working in multi-color too.

 

use the Image(systemName:) initializer, passing in the icon string to load.

Image(systemName: "cloud.heavyrain.fill")
Back

A preview provider returns

Front

A preview provider returns one or more views, with options to configure the size and device.

Back

SwiftUI Map

Front
import MapKit
import SwiftUI

struct ContentView: View {
    @State private var region = 
    	MKCoordinateRegion(
    		center: 
    			CLLocationCoordinate2D(
    				latitude: 51.507222, 
    				longitude: -0.1275), 
    		span: 
    			MKCoordinateSpan(
    				latitudeDelta: 0.5, 
    				longitudeDelta: 0.5))

    var body: some View {
        Map(coordinateRegion: $region)
    }
}
Back

Pass Data into Child Views(NavigationLink)

Front

the views it comprises need to use a stored property as the source for their data. Starting with the child views, you’ll convert all the views to display data that’s passed in. This is a common pattern when building views using SwiftUI. Your custom views will often wrap and encapsulate a series of modifiers for a particular view. Pass the required data down to your custom types. Finally, call the navigationBarTitle(_:displayMode:) modifier to give the navigation bar a title when showing the detail view.

struct LandmarkDetail: View
. . .
var landmark: Landmark
. . .
var body: some View {
    VStack {
     . . .
    }
    .navigationBarTitle(landmark.name, displayMode: .inline)
}
struct LandmarkList: View
. . .
NavigationView{
    List(landmarkData) { landmark in
        NavigationLink(
        	destination: 
        		LandmarkDetail(
        			landmark: landmark)){
            LandmarkRow(landmark: landmark)
        }
    }
    .navigationTitle("Landmarks")
}
Back

navigationBarTitle(_:displayMode:)

Front

The navigationBarTitle(_:displayMode:) modifier to give the navigation bar a title when showing the detail view.

struct LandmarkDetail: View {
    var landmark: Landmark

    var body: some View {
        VStack {
			. . .
        }
        .navigationBarTitle(
        	landmark.name, 
        	displayMode: .inline)
    }
}
Back

Embed in VStack

Front

Command-click the view’s to show the structured editing popover, and then choose Embed in VStack

 

Back

binding

Front

A binding acts as a reference to a mutable state. The control uses the binding to update the view’s state accordingly.

 

You use the $ prefix to access a binding to a state variable, or one of its properties.

struct LandmarkList: View {
@State var showFavoritesOnly = true

var body: some View {
    NavigationView {
        List {
            Toggle(isOn: $showFavoritesOnly) {
                Text("Favorite Only")
            }
            ForEach(landmarkData) { landmark in
				. . .
            }
        }
Back

previewLayout(_:) 

Front

Use previewLayout(_:) to set a custom frame size.

struct LandmarkRow_Previews: PreviewProvider {
    static var previews: some View {
        LandmarkRow(
        	landmark: landmarkData[1])
            .previewLayout(
            	.fixed(width: 300, 
            		   height: 70))
    }
}
Back

You can combine and embed multiple views in

Front

stacks, which group views together horizontally, vertically, or back-to-front.

Back

Identifiable protocol

Front

When conforming to the protocol Identifiable we have to implement a variable called id however this variable does not have to be an Int. The protocol only requires that the type of the variable id is actually Hashable.

 

Note: Int, Double, String and a lot more types are Hashable

struct Landmark: Hashable, Codable, Identifiable {
    var id: Int
    var name: String
    var state: String
    var park: String
}
Back

Use an Observable Object for Storage

Front

An observable object is a custom object for your data that can be bound to a view from storage in SwiftUI’s environment. SwiftUI watches for any changes to observable objects that could affect a view, and displays the correct version of the view after a change.

  1. Declare a new model type that conforms to the ObservableObject protocol from the Combine framework.
  2. SwiftUI subscribes to your observable object, and updates any views that need refreshing when the data changes.
  3. Add stored properties, along with their initial values.
  4. An observable object needs to publish any changes to its data, so that its subscribers can pick up the change. Add the @Published attribute to each property in the model.
import Foundation
import Combine

final class UserData: ObservableObject {
    @Published var showFavoritesOnly = false
    @Published var landmarks = landmarkData
}
Back

the body property only returns

Front

a single view

Back

previewDisplayName(_:)

Front

The previewDisplayName(_:) modifier, lets you put a name under a device in the preview window.

#if DEBUG
struct ContentView_Previews: PreviewProvider {
   static var previews: some View {
      Group {
         ContentView()
            .previewDevice(
            	PreviewDevice(rawValue: "iPhone SE"))
            .previewDisplayName("iPhone SE")

         ContentView()
            .previewDevice(
            	PreviewDevice(rawValue: "iPhone XS Max"))
            .previewDisplayName("MY CUSTOM NAME")
      }
   }
}
#endif
Back

scale up an icons from Apple’s SF Symbols set

Front
Image(systemName: "cloud.heavyrain.fill")
    .font(.largeTitle)
Back

PreviewProvider customization

Front

You can customize the returned content from a preview provider to render exactly the previews that are most helpful to you.

 

The code you write in a preview provider only changes what Xcode displays in the canvas.

Back

When using a List or ForEach  on primitive types that don’t conform to the Identifiable protocol

Front

When using a List or ForEach on primitive types that don’t conform to the Identifiable protocol, such as an array of strings or integers. You should use id: \.self as the second parameter to your List or ForEach.

let data =  
	["Robert", "Esmery", 
	 "Mami", "Papi"]

VStack {
    ForEach(data, id: \.self){ pos in
        Text("Hello \(pos)")
    }
}
Back

Color an icons from Apple’s SF Symbols set

Front
Image(systemName: "cloud.heavyrain.fill")
                .foregroundColor(.red)
Back

Create a Conditional Button

Front

Create a new button using an if-else conditional statement.

In the button’s action closure, the code uses landmarkIndex with the userData object to update.

Button(
    action:
        {self.userData.landmarks[self.landmarkIndex]
            .isFavorite.toggle()}) {
    if self.userData.landmarks[self.landmarkIndex]
            .isFavorite {
        Image(systemName: "star.fill")
            .foregroundColor(.yellow)
    } else {
        Image(systemName: "star")
            .foregroundColor(.gray)
    }
Back

Format Code / Balance indentation

Front

⌘ + A, ⌃ + I

Back

Generating Previews Dynamically

Front

By default, previews render at the size of the device in the active scheme. You can change the preview device by calling the previewDevice(_:) modifier method.

 

ForEach operates on collections the same way as the list, which means you can use it anywhere you can use a child view, such as in stacks, lists, groups, and more. When the elements of your data are simple value types — like the strings you’re using here — you can use \.self as key path to the identifier.

 

Use the previewDisplayName(_:)modifier to add the device names as labels for the previews.

struct LandmarkList_Previews: PreviewProvider {
    static var previews: some View {
        ForEach(
        	["iPhone 11", "iPhone 11 Pro Max"], 
        	id: \.self) { 
        		deviceName in
            	LandmarkList()
                	.previewDevice(
                		PreviewDevice(
                			rawValue: deviceName))
                	.previewDisplayName(deviceName)
        }
    }
}
Back

combining static and dynamic views in a list, or to combine two or more different groups of dynamic views.

Front

To combine static and dynamic views in a list, or to combine two or more different groups of dynamic views, use the ForEach type instead of passing your collection of data to List.

struct LandmarkList: View {
@State var showFavoritesOnly = true

var body: some View {
NavigationView {
List {
    Toggle(isOn: $showFavoritesOnly) {
        Text("Favorite Only")
    }
    ForEach(landmarkData) { landmark in
        if !self.showFavoritesOnly ||
            landmark.isFavorite {
            
            NavigationLink(
                destination:
                    LandmarkDetail(landmark: landmark)) {
                LandmarkRow(landmark: landmark)
            }
        }
    }
}
.navigationBarTitle("Landmarks")
Back

Toggle Minimap

Front

⇧ + ⌃ + ⌘ + M

Back

navigationBarTitle

Front

the navigationBarTitle(_:) modifier method to set the title of the navigation bar when displaying the list.

NavigationView{
    List(landmarkData) { landmark in
        LandmarkRow(landmark: landmark)
    }
    .navigationTitle("Landmarks")
}
Back

State

Front

State is a value, or a set of values, that can change over time, and that affects a view’s behavior, content, or layout. You use a property with the @State attribute to add state to a view.

struct LandmarkList: View {
    @State var showFavoritesOnly = false
Back

Toggle canvas / preview shortcut

Front

⌥ + ⌘ + ↩

Back

Show SwiftUI Inspector...(Canvas)

Front

⌃ + ⌥ + Click

Back

Refresh Canvas/Resume Preview

Front

⌥ + ⌘ + P

Back

New File

Front

⌘ + N

Back

Dynamic List

Front

Instead of specifying a list’s elements individually, you can generate rows directly from a collection.

You can create a list that displays the elements of collection by passing your collection of data and a closure that provides a view for each element in the collection. The list transforms each element in the collection into a child view by using the supplied closure. Lists work with identifiable data. You can make your data identifiable in one of two ways: by passing along with your data a key path to a property that uniquely identifies each element, or by making your data type conform to the Identifiable protocol.

List(landmarkData, id: \.id) { landmark in
    LandmarkRow(landmark: landmark)
}
List(landmarkData) { landmark in
    LandmarkRow(landmark: landmark)
}
Back

in SwiftUI view, you describe its content, layout, and behavior in

Front

the view’s body property;

Back

Applying various properties to an icons from Apple’s SF Symbols set.

Front
Image(systemName: "cloud.sun.rain.fill")
    .renderingMode(.original)
    .font(.largeTitle)
    .padding()
    .background(Color.black)
    .clipShape(Circle())
Back

List

Front

SwiftUI’s List type, can display a platform-specific list of views. The elements of the list can be static, or dynamically generated. You can even mix static and dynamically generated views.

List {
    LandmarkRow(landmark: landmarkData[0])
    LandmarkRow(landmark: landmarkData[1])
}
Back

Tab Library

Front

⌃ + Tab

Back

Show Code Actions

Front

⌘ + Click or ⇧ + ⌘ + A

Back

Adopt the Model Object in Your Views

Front

Once you have the  Model object, you need to update your views to adopt it as the data store for your app.

 

replace the properties declaration with an @EnvironmentObject property, and add an environmentObject(_:) modifier to the preview.

 

This property gets its value automatically, as long as the environmentObject(_:) modifier has been applied to a parent.

 

Make sure the code is accessing the new property.

 

Just like on @State properties, you can access a binding to a member of the new property object by using the $ prefix.

 

You’ll use landmarkIndex when accessing or updating the landmark’s favorite status, so that you’re always accessing the correct version of that data.

Back

Xcode keyboard shortcuts 

Front
Back

Navigation Between List and Detail

Front

You add navigation capabilities to a list by embedding it in a NavigationView, and then nesting each row in a NavigationLink to set up a transtition to a destination view.

NavigationView{
    List(landmarkData) { landmark in
        NavigationLink(
        	destination: LandmarkDetail()){
             LandmarkRow(landmark: landmark)
        }
    }
    .navigationTitle("Landmarks")
}

 

Back