세번째 데모는 입력 처리 추가하기 입니다.
아래의 링크에서 프로젝트를 다운로드 받아서 StartingPoing폴더에 있는 프로젝트를 오픈하면 됩니다.
아래의 링크에서 프로젝트를 다운로드 받아서 StartingPoing폴더에 있는 프로젝트를 오픈하면 됩니다.
사용자가 랜드마크를 보고 별표 표시를 하는 경우
StartingPoing폴더에 있는 시작 프로젝트를 오픈 합니다.
LandmarkRow파일에서 아래와 같이 수정합니다.
LandmarkRow파일에서 아래와 같이 수정합니다.
import SwiftUI
struct LandmarkRow: View {
var landmark: Landmark
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")
.imageScale(.medium)
}
}
}
}
LandmarkList를 아래와 같이 수정합니다.
import SwiftUI
import SwiftUI
struct LandmarkList: View {
@State var showFavoritesOnly = false
var body: some View {
NavigationView {
List(landmarkData) { landmark in
if !self.showFavoritesOnly ||
landmark.isFavorite {
NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
LandmarkRow(landmark: landmark)
}
}
}
.navigationBarTitle(Text("Landmarks"))
}
}
}
Section 3: 상태를 토글하기 위해 컨트롤을 추가합니다.
유저가 리스트 필터링을 컨트롤하도록, 컨트롤을 추가합니다.
LandmarkList를 수정합니다.
유저가 리스트 필터링을 컨트롤하도록, 컨트롤을 추가합니다.
LandmarkList를 수정합니다.
import SwiftUI
struct LandmarkList: View {
@State var showFavoritesOnly = true
var body: some View {
NavigationView {
List {
ForEach(landmarkData) { landmark in
if !self.showFavoritesOnly ||
landmark.isFavorite {
NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
LandmarkRow(landmark: landmark)
}
}
}
}
.navigationBarTitle(Text("Landmarks"))
}
}
}
다시 아래와 같이 추가합니다.
import SwiftUI
import SwiftUI
struct LandmarkList: View {
@State var showFavoritesOnly = true
var body: some View {
NavigationView {
List {
Toggle(isOn: $showFavoritesOnly) {
Text("Favorites only")
}
ForEach(landmarkData) { landmark in
if !self.showFavoritesOnly ||
landmark.isFavorite {
NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
LandmarkRow(landmark: landmark)
}
}
}
}
.navigationBarTitle(Text("Landmarks"))
}
}
}
Section 4: Storage를 위해 Observable Object를 사용한다.
좋아하는 랜드마크를 컨트롤하도록 준비하기 위해 먼저 observable object로
랜드마크 데이터를 저장해야 합니다.
observable object는 storage로 부터 SwiftUI환경으로 뷰를 바운드할 수 있습니다.
SwiftUI는 뷰에 영향을 주는 observable object에 대한 변경을 감시하고,
그리고 변경후에 뷰의 올바른 버전을 표시합니다.
좋아하는 랜드마크를 컨트롤하도록 준비하기 위해 먼저 observable object로
랜드마크 데이터를 저장해야 합니다.
observable object는 storage로 부터 SwiftUI환경으로 뷰를 바운드할 수 있습니다.
SwiftUI는 뷰에 영향을 주는 observable object에 대한 변경을 감시하고,
그리고 변경후에 뷰의 올바른 버전을 표시합니다.
Models폴더에 UserData.swift파일을 추가해서 아래와 같이 코딩 합니다.
import SwiftUI
import Combine
import SwiftUI
import Combine
final class UserData : ObservableObject {
@Published var showFavoritesOnly = false
@Published var landmarks = landmarkData
}
@Published var showFavoritesOnly = false
@Published var landmarks = landmarkData
}
Section 5: 뷰에 Model Object을 붙이기
UserData 오브젝트를 생성한 후에 앱의 데이터 저장으로 뷰를 적용하도록 업데이트합니다.
UserData 오브젝트를 생성한 후에 앱의 데이터 저장으로 뷰를 적용하도록 업데이트합니다.
LandmarkList를 수정합니다.
import SwiftUI
import SwiftUI
struct LandmarkList: View {
//다음과 같이 수정한다.
@EnvironmentObject var userData: UserData
var body: some View {
NavigationView {
List {
Toggle(isOn: $userData.showFavoritesOnly) {
Text("Favorites only")
}
ForEach(userData.landmarkData) { landmark in
if !self.userData.showFavoritesOnly ||
landmark.isFavorite {
NavigationLink(destination: LandmarkDetail(landmark: landmark)) {
LandmarkRow(landmark: landmark)
}
}
}
}
.navigationBarTitle(Text("Landmarks"))
}
}
}
struct LandmarkList_Previews: PreviewProvider {
static var previews: some View {
LandmarkList()
.environmentObject(UserData())
}
}
static var previews: some View {
LandmarkList()
.environmentObject(UserData())
}
}
SceneDelegate도 수정합니다.
import UIKit
import SwiftUI
import UIKit
import SwiftUI
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Use a UIHostingController as window root view controller
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(
rootView: LandmarkList()
.environmentObject(UserData())
)
self.window = window
window.makeKeyAndVisible()
}
}
LandmarkDetail을 수정합니다.
import SwiftUI
import SwiftUI
struct LandmarkDetail: View {
@EnvironmentObject var userData: UserData
var landmark: Landmark
@EnvironmentObject var userData: UserData
var landmark: Landmark
var landmarkIndex: Int {
userDAta.landmarks.firstIndex(
where: { $0.id == landmark.id })!
}
var body: some View {
VStack {
MapView(coordinate: landmark.locationCoordinate)
.frame(height: 300)
CircleImage(image: landmark.image)
.offset(x: 0, y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text(landmark.name)
.font(.title)
HStack(alignment: .top) {
Text(landmark.park)
.font(.subheadline)
Spacer()
Text(landmark.state)
.font(.subheadline)
}
}
.padding()
Spacer()
}
.navigationBarTitle(Text(verbatim: landmark.name), displayMode: .inline)
}
}
struct LandmarkDetail_Previews: PreviewProvider {
static var previews: some View {
LandmarkDetail(landmark: landmarkData[0])
.environmentObject(UserData())
}
}
static var previews: some View {
LandmarkDetail(landmark: landmarkData[0])
.environmentObject(UserData())
}
}
Section 6: 각 랜드마크에 대한 Favorite 버튼을 생성합니다.
LandmarkDetail을 수정합니다.
import SwiftUI
import SwiftUI
struct LandmarkDetail: View {
@EnvironmentObject var userData: UserData
var landmark: Landmark
@EnvironmentObject var userData: UserData
var landmark: Landmark
var landmarkIndex: Int {
userData.landmarks.firstIndex(where: { $0.id == landmark.id })!
}
var body: some View {
VStack {
MapView(coordinate: landmark.locationCoordinate)
.edgesIgnoringSafeArea(.top)
.frame(height: 300)
CircleImage(image: landmark.image)
.offset(x: 0, y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
HStack {
Text(verbatim: 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(verbatim: landmark.park)
.font(.subheadline)
Spacer()
Text(verbatim: landmark.state)
.font(.subheadline)
}
}
.padding()
Spacer()
}
}
}
struct LandmarkDetail_Preview: PreviewProvider {
static var previews: some View {
let userData = UserData()
return LandmarkDetail(landmark: userData.landmarks[0])
.environmentObject(userData)
}
}
static var previews: some View {
let userData = UserData()
return LandmarkDetail(landmark: userData.landmarks[0])
.environmentObject(userData)
}
}
실행하면 다음과 같습니다.
댓글 없음:
댓글 쓰기
참고: 블로그의 회원만 댓글을 작성할 수 있습니다.