2020년 1월 11일 토요일

iOS 13.*에 추가된 SwiftUI의 입력 처리하기 입니다.

세번째 데모는 입력 처리 추가하기 입니다.
아래의 링크에서 프로젝트를 다운로드 받아서 StartingPoing폴더에 있는 프로젝트를 오픈하면 됩니다.
사용자가 랜드마크를 보고 별표 표시를 하는 경우
스크린샷 2019-10-07 오후 4.18.52.png
StartingPoing폴더에 있는 시작 프로젝트를 오픈 합니다.
LandmarkRow파일에서 아래와 같이 수정합니다.
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")
                .imageScale(.medium)
        }
    }
}
}
Section 2: List View를 필터링하기
사용자가 좋아하는 것만 필터링할 수 있습니다.
View에 상태를 추가하기 위해 @State속성을 사용할 수 있습니다.
LandmarkList를 아래와 같이 수정합니다.
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를 수정합니다.
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
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"))
    }
}
}
스크린샷 2019-10-07 오후 4.11.38.png
Section 4: Storage를 위해 Observable Object를 사용한다.
좋아하는 랜드마크를 컨트롤하도록 준비하기 위해 먼저 observable object로
랜드마크 데이터를 저장해야 합니다.
observable object는 storage로 부터 SwiftUI환경으로 뷰를 바운드할 수 있습니다.
SwiftUI는 뷰에 영향을 주는 observable object에 대한 변경을 감시하고,
그리고 변경후에 뷰의 올바른 버전을 표시합니다.
Models폴더에 UserData.swift파일을 추가해서 아래와 같이 코딩 합니다.
import SwiftUI
import Combine
final class UserData : ObservableObject {
@Published var showFavoritesOnly = false
@Published var landmarks = landmarkData
}
Section 5: 뷰에 Model Object을 붙이기
UserData 오브젝트를 생성한 후에 앱의 데이터 저장으로 뷰를 적용하도록 업데이트합니다.
LandmarkList를 수정합니다.
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())
}
}
SceneDelegate도 수정합니다.
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
struct LandmarkDetail: View {
@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())
}
}
Section 6: 각 랜드마크에 대한 Favorite 버튼을 생성합니다.
LandmarkDetail을 수정합니다.
import SwiftUI
struct LandmarkDetail: View {
@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)
}
}
실행하면 다음과 같습니다.

스크린샷 2019-10-07 오후 4.46.32.png
스크린샷 2019-10-07 오후 4.46.40.png

댓글 없음:

댓글 쓰기

참고: 블로그의 회원만 댓글을 작성할 수 있습니다.

'일론 머스크' '젠슨 황' AI 리더들, 그들의 성공 비결은 바로 이것 - 누가 부자가 되는가 영상입니다. ㅎㅎ

  책을 통해서만 접했던 내용들을 영상으로 보니 더 실감이 납니다. KBS에서 방송된 내용인데 주말에 보시면 좋은 영상입니다. 엔비디아의 주가가 이해가 됩니다. ㅋㅋ 생각보다 미국시장이 강한 것이 AI는 거의 미국과 중국이 주도하는 시장이 되고 있습...