0% found this document useful (0 votes)
10 views

SwiftUI-3-Handling User Input

Uploaded by

Tâm Trần
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

SwiftUI-3-Handling User Input

Uploaded by

Tâm Trần
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 27

3.

SwiftUI
1
Marketing /
Report
- Handling user input

1
3.SwiftUI
2
Marketing /
Report
- Handling user input

2
import Foundation
3.SwiftUI
3 - Handling user input import SwiftUI
import CoreLocation

struct Landmark: Hashable, Codable, Identifiable


{
var id: Int
var name: String
var park: String
var state: String
var description: String
var isFavorite: Bool

private var imageName: String


var image: Image {
Image(imageName)
}

private var coordinates: Coordinates


var locationCoordinate:
CLLocationCoordinate2D {
CLLocationCoordinate2D(
latitude: coordinates.latitude,
longitude: coordinates.longitude)
}

struct Coordinates: Hashable, Codable {


Marketing /

var latitude: Double


var longitude: Double
}
Report

Landmark.swift
3
import SwiftUI
3.SwiftUI
4 - Handling user input
struct LandmarkRow: View {
var landmark: Landmark

var body: some View {


HStack {
landmark.image
.resizable()
.frame(width: 50, height: 50)
Text(landmark.name)

Spacer()

if landmark.isFavorite {
Image(systemName: "star.fill")
}
}
}
}

#Preview {
Group {
LandmarkRow(landmark: landmarks[0])
LandmarkRow(landmark: landmarks[1])
}
Marketing /

}
Report

LandmarkRow.swift
4
3.SwiftUI
5 - Handling user input import SwiftUI

struct LandmarkRow: View {


var landmark: Landmark

var body: some View {


HStack {
landmark.image
.resizable()
.frame(width: 50, height: 50)
Text(landmark.name)

Spacer()

if landmark.isFavorite {
Image(systemName: "star.fill")
.foregroundStyle(.yellow)
}
}
}
}

#Preview {
Group {
Marketing /

LandmarkRow(landmark: landmarks[0])
LandmarkRow(landmark: landmarks[1])
}
Report

LandmarkRow.swift
5
3.SwiftUI
6
Marketing /
Report
- Handling user input

6
3.SwiftUI
7 - Handling user input import SwiftUI

struct LandmarkList: View {


@State private var showFavoritesOnly = false

var body: some View {


NavigationSplitView {
List(landmarks) { landmark in
NavigationLink {
LandmarkDetail(landmark:
landmark)
} label: {
LandmarkRow(landmark:
landmark)
}
}
.navigationTitle("Landmarks")
} detail: {
Text("Select a Landmark")
}
}
}

#Preview {
LandmarkList()
}
Marketing /
Report

LandmarkList.swift
7
3.SwiftUI
8
Marketing /
Report
- Handling user input

8
3.SwiftUI
9 - Handling user input import SwiftUI

struct LandmarkList: View {


@State private var showFavoritesOnly
= true

var filteredLandmarks: [Landmark] {


landmarks.filter { landmark in
(!showFavoritesOnly ||
landmark.isFavorite)
}
}

var body: some View {


NavigationSplitView {
List(filteredLandmarks) {
landmark in
NavigationLink {

LandmarkDetail(landmark: landmark)
} label: {

LandmarkRow(landmark: landmark)
}
}

.navigationTitle("Landmarks")
} detail: {
Text("Select a Landmark")
}
}
}
Marketing /

#Preview {
Report

LandmarkList()
}

LandmarkList.swift
9
3.SwiftUI
10
Marketing /
Report
- Handling user input

10
3.SwiftUI
11 - Handling user input import SwiftUI

struct LandmarkList: View {


@State private var showFavoritesOnly =
true

var filteredLandmarks: [Landmark] {


landmarks.filter { landmark in
(!showFavoritesOnly ||
landmark.isFavorite)
}
}

var body: some View {


NavigationSplitView {
List {
Toggle(isOn:
$showFavoritesOnly) {
Text("Favorites only")
}

ForEach(filteredLandmarks) {
landmark in
NavigationLink {

LandmarkDetail(landmark: landmark)
} label: {
LandmarkRow(landmark:
landmark)
}
}
}
.navigationTitle("Landmarks")
} detail: {
Text("Select a Landmark")
Marketing /

}
}
}
Report

LandmarkList.swift #Preview {
LandmarkList()
}

11
3.SwiftUI
12 - Handling user input import SwiftUI

struct LandmarkList: View {


@State private var showFavoritesOnly = false

var filteredLandmarks: [Landmark] {


landmarks.filter { landmark in
(!showFavoritesOnly || landmark.isFavorite)
}
}

var body: some View {


NavigationSplitView {
List {
Toggle(isOn: $showFavoritesOnly) {
Text("Favorites only")
}

ForEach(filteredLandmarks) { landmark in
NavigationLink {
LandmarkDetail(landmark: landmark)
} label: {
LandmarkRow(landmark: landmark)
}
}
}
.animation(.default, value: filteredLandmarks)
.navigationTitle("Landmarks")
} detail: {
Text("Select a Landmark")
}
}
}
Marketing /

#Preview {
LandmarkList()
}
Report

LandmarkList.swift
12
3.SwiftUI
13
Marketing /
Report
- Handling user input

13
3.SwiftUI
14
Marketing /
Report
- Handling user input

14
3.SwiftUI
15 - Handling user input import Foundation

@Observable
class ModelData {
var landmarks: [Landmark] = load("landmarkData.json")
}

func load<T: Decodable>(_ filename: String) -> T {


let data: Data

guard let file = Bundle.main.url(forResource: filename,


withExtension: nil)
else {
fatalError("Couldn't find \(filename) in main bundle.")
}

do {
data = try Data(contentsOf: file)
} catch {
fatalError("Couldn't load \(filename) from main
bundle:\n\(error)")
}

do {
let decoder = JSONDecoder()
return try decoder.decode(T.self, from: data)
} catch {
fatalError("Couldn't parse \(filename) as
\(T.self):\n\(error)")
}
Marketing /

}
ModelData.swift
Report

15
3.SwiftUI
16
Marketing /
Report
- Handling user input

16
3.SwiftUI
17 - Handling user input import SwiftUI

struct LandmarkList: View {


@Environment(ModelData.self) var modelData
@State private var showFavoritesOnly = false

var filteredLandmarks: [Landmark] {


modelData.landmarks.filter { landmark in
(!showFavoritesOnly || landmark.isFavorite)
}
}

var body: some View {


NavigationSplitView {
List {
Toggle(isOn: $showFavoritesOnly) {
Text("Favorites only")
}

ForEach(filteredLandmarks) { landmark in
NavigationLink {
LandmarkDetail(landmark: landmark)
} label: {
LandmarkRow(landmark: landmark)
}
}
}
.animation(.default, value: filteredLandmarks)
.navigationTitle("Landmarks")
} detail: {
Text("Select a Landmark")
}
}
Marketing /

}
Report

#Preview {
LandmarkList()
.environment(ModelData())
}

17
LandmarkList.swift
3.SwiftUI
18 - Handling user input import SwiftUI

struct LandmarkDetail: View {


var landmark: Landmark

var body: some View {


ScrollView {
MapView(coordinate: landmark.locationCoordinate)
.frame(height: 300)

CircleImage(image: landmark.image)
.offset(y: -130)
.padding(.bottom, -130)

VStack(alignment: .leading) {
Text(landmark.name)
.font(.title)

HStack {
Text(landmark.park)
Spacer()
Text(landmark.state)
}
.font(.subheadline)
.foregroundStyle(.secondary)

Divider()

Text("About \(landmark.name)")
.font(.title2)
Text(landmark.description)
}
.padding()
}
Marketing /

.navigationTitle(landmark.name)
.navigationBarTitleDisplayMode(.inline)
}
}
Report

#Preview {
LandmarkDetail(landmark: ModelData().landmarks[0])
}

18
LandmarkDetail.swift
3.SwiftUI
19 - Handling user input import SwiftUI

struct LandmarkRow: View {


var landmark: Landmark

var body: some View {


HStack {
landmark.image
.resizable()
.frame(width: 50, height: 50)
.cornerRadius(5)
Text(landmark.name)

Spacer()

if landmark.isFavorite {
Image(systemName: "star.fill")
.imageScale(.medium)
.foregroundStyle(.yellow)
}
}
}
}

#Preview {
let landmarks = ModelData().landmarks
return Group {
LandmarkRow(landmark: landmarks[0])
Marketing /

LandmarkRow(landmark: landmarks[1])
}
}
Report

19
LandmarkRow.swift
3.SwiftUI
20 - Handling user input import SwiftUI

struct ContentView: View {


var body: some View {
LandmarkList()
}
}

#Preview {
ContentView()
.environment(ModelData())
}

ContentView.swift

import SwiftUI

@main
struct LandmarksApp: App {
@State private var modelData = ModelData()

var body: some Scene {


WindowGroup {
ContentView()
.environment(modelData)
}
}
}
Marketing /

LandmarksApp.swift
Report

20
3.SwiftUI
21
Marketing /
Report
- Handling user input

21
3.SwiftUI
22
Marketing /
Report
- Handling user input

22
3.SwiftUI
23 - Handling user input
import SwiftUI

struct FavoriteButton: View {


@Binding var isSet: Bool

var body: some View {


Text("Hello, World!")
}
}

#Preview {
FavoriteButton(isSet:
.constant(true))
}

FavoriteButton.swift
Marketing /
Report

23
3.SwiftUI
24 - Handling user input

import SwiftUI

struct FavoriteButton: View {


@Binding var isSet: Bool

var body: some View {


Button {
isSet.toggle()
} label: {
Marketing /

Label("Toggle Favorite", systemImage: isSet ?


"star.fill" : "star")
.labelStyle(.iconOnly)
.foregroundStyle(isSet ? .yellow : .gray)
}
Report

}
FavoriteButton.swift }

#Preview {
FavoriteButton(isSet: .constant(true))
}
Landmarks Helper 24
3.SwiftUI
25 - Handling user input import SwiftUI

struct LandmarkDetail: View {


@Environment(ModelData.self) var modelData
var landmark: Landmark

var landmarkIndex: Int {


modelData.landmarks.firstIndex(where: { $0.id == landmark.id })!
}

var body: some View {


ScrollView {
MapView(coordinate: landmark.locationCoordinate)
.frame(height: 300)

CircleImage(image: landmark.image)
.offset(y: -130)
.padding(.bottom, -130)

VStack(alignment: .leading) {
Text(landmark.name)
.font(.title)

HStack {
Text(landmark.park)
Spacer()
Text(landmark.state)
}
.font(.subheadline)
.foregroundStyle(.secondary)

Divider()

Text("About \(landmark.name)")
.font(.title2)
Text(landmark.description)
}
.padding()
}
Marketing /

.navigationTitle(landmark.name)
.navigationBarTitleDisplayMode(.inline)
}
}
Report

#Preview {
let modelData = ModelData()
return LandmarkDetail(landmark: modelData.landmarks[0])
.environment(modelData)
}

LandmarkDetail.swift 25
3.SwiftUI
26 - Handling user input import SwiftUI

struct LandmarkDetail: View {


@Environment(ModelData.self) var modelData
var landmark: Landmark

var landmarkIndex: Int {


modelData.landmarks.firstIndex(where: { $0.id == landmark.id })!
}

var body: some View {


@Bindable var modelData = modelData

ScrollView {
MapView(coordinate: landmark.locationCoordinate)
.frame(height: 300)

CircleImage(image: landmark.image)
.offset(y: -130)
.padding(.bottom, -130)

VStack(alignment: .leading) {
HStack {
Text(landmark.name)
.font(.title)
FavoriteButton(isSet: $modelData.landmarks[landmarkIndex].isFavorite)
}

HStack {
Text(landmark.park)
Spacer()
Text(landmark.state)
}
.font(.subheadline)
.foregroundStyle(.secondary)

Divider()

Text("About \(landmark.name)")
.font(.title2)
Text(landmark.description)
}
Marketing /

.padding()
}
.navigationTitle(landmark.name)
.navigationBarTitleDisplayMode(.inline)
}
Report

#Preview {
let modelData = ModelData()
return LandmarkDetail(landmark: modelData.landmarks[0])
.environment(modelData)
LandmarkDetail.swift } 1
3.SwiftUI
27
Marketing /
Report
- Handling user input

27

You might also like