見出し画像

Swiftで行こう!--SwiftUIで行こう!6

SwiftUIで行こう!3 の続き、星マークの追加できるようにします。この動作は保存されません。

まず新規ファイルUserData.swiftを作るとこからです。コードは

import SwiftUI
import Combine
final class UserData:BindableObject{
   let didChange = PassthroughSubject<UserData,Never>()
   
   var showFavaritesOnly = false{
       didSet{
           didChange.send(self)
       }
   }
   var landmarks = landmarkData{
       didSet{
           didChange.send(self)
       }
   }
}

LandmarkList.swiftでUserDateを呼び出す時には

@EnvironmentObject var userData: UserData

@EnvironmentObjectを使うようです。

struct LandmarkListで 

@State var showFavaritesOnly = false

を削除して

@EnvironmentObject var userData: UserData

に置き換えます。そして変数

showFavoritesOnly

のところを

userData.showFavoritesOnly

とします。class UserDataを呼び出して値を入れていきます。

ForEach(landmarkData)も

ForEach(luserData.landmarks)

とします。

次 SceneDelegate.swiftです。

window.rootViewController = UIHostingController(
rootView: LandmarkList()
.environmentObject(UserData())
)

に変更します。

最後にLandmarkDetail.swiftを変更していきます。

@EnvironmentObject var userData: UserData

をstruct LandmarkDetail: View{}の最初に宣言します。

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.

ということでvar landmark: Landmarkの直下に

 var landmarkIndex: Int {
       userData.landmarks.firstIndex(where: { $0.id == landmark.id })!
   }

を追加します。favorite status(星マーク)のあるなしの情報を受け取ります。

そしてfavorite statusのボタンを作っていきます。

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

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

               }
               HStack(alignment: .top) {
                   Text(landmark.park)
                       .font(caption)
                   Spacer()
                   Text(landmark.state)
                       .font(.caption)
               }
           }
Button(action: {
self.userData.landmarks[self.landmarkIndex].isFavorite.toggle()
}) {
if self.userData.landmarks[self.landmarkIndex].isFavorite {
Image(systemName: "star.fill")
.foregroundColor(Color.yellow)
} else {
Image(systemName: "star")
.foregroundColor(Color.gray)
}
}

のようにボタンを設置します。

これでボタンを押すと星マークが付きもう一度押すと消えるマークが出来ました。




この記事が気に入ったらサポートをしてみませんか?