Ch1 - 3 | Handling User Input

Joni·2023년 4월 4일
0

SwiftUI

목록 보기
3/3
post-thumbnail

SwiftUI 스터디 3주차 !!

Ch1-3. Handling User Input

1. Mark the User’s Favorite Landmarks

(간단요약) step1 ~step5: data Struct에 isFavorite 변수를 추가해주고, LandmarkRow에서 해당 변수가 보이는 별 이미지 추가

var body: some View {
        HStack {
            landmark.image
                .resizable()
                .frame(width: 50, height: 50)
            Text(landmark.name)
            
            Spacer()
            
            if landmark.isFavorite {
                Image(systemName: "star.fill")
                    .foregroundColor(.yellow)
            }
        }
    }

2.Filter the List View

(간단요약) step1 ~step6: ListView에서 필터 기능 보여주기

  • LandMarkList에서 새로운 filteredLandmarks 배열을 만들어준다.

    • 조건 1: !showFavoritesOnly가 ture 이거나?
    • 조건 2: isFavorite이 true 인가?
      그래서 showFavoritesOnly가 false인경우는 모든 배열의 요소가 새로운 배(filteredLandmarks)에 들어가고 true인 경우 isFavorite이 true인것만 새로운 filter 배열에 들어간다.
  • 마지막으로 filter 배열을을 body 안에 있는 List 안에서 보여준다.

	@State private var showFavoritesOnly = false

    var filteredLandmarks: [Landmark] {
        landmarks.filter{
            landmark in (!showFavoritesOnly || landmark.isFavorite)
        }
    }

3. Add a Control to Toggle the State

(간단요약) step1 ~step4:Toggle 버튼 생성해서 변수 관리하기

  • Toggle을 사용하여 showFavoritesOnly 변수를 연결해준다.

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

4. Use an Observable Object for Storage

(간단요약) step1 ~step4: import Combine해주고 ObservableObject class 생성

import Combine

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

Combine이란?

시간 경과에 따라 변경되는 값을 내보내는 Publisher와 이를 수신하는 Subscriber로 시간 경과에 따른 값 처리를 위한 선언적 Swift API입니다.

  • Publisher
    • Publisher는 하나 혹은 여러 개의 Subscriber 객체에 시간이 흐름에 따라 값을 내보낼 수 있는 타입을 선언하기 위한 프로토콜입니다.
    • Output, Failure 타입이 제네릭으로 구현되어 있습니다.
  • Subscriber
    • Subscriber는 Publisher에게 값을 받을 수 있는 타입을 선언하기 위한 프로토콜입니다.
    • Input, Failure 타입이 제네릭으로 구현되어 있습니다.
  • Operator
    • Operator는 Publisher를 반환하는 Publisher 프로토콜에 정의된 메서드들입니다.
    • 여러 종류의 Operator를 Combine 하여 사용하여 Publisher가 내보내는 값을 처리합니다.
    • Upstream, DownStream이라고 하는 Input, Output을 가지고 있습니다.
  • Subscription
    • Subscription은 Publisher와 Subscriber의 연결을 나타내는 프로토콜입니다.
    • 간단하게 말해서 Publisher + Operator + Subscriber로 이뤄진 하나의 작업이 Subscription입니다.

참고자료 1
참고자료 2

Observable Object란?

기본적으로 Combine에 포함된 기능으로 ObservableObject는 @Published 프로퍼티 래퍼가 붙은 값이 변경되기 전에, 변경된 값을 방출(emit)하는 objectWillChange 퍼블리셔를 사용할 수 있도록 하는 프로토콜입니다. (클래스에서만 사용 가능한 프로토콜입니다.)

@Published 속성 래퍼(Property Wrapper)란?

SwiftUI에서 가장 유용한 속성 래퍼 중 하나이며 변경이 발생할 때 자동으로 알리는 관찰 가능한 오브젝트(observable object)를 만들 수 있습니다. SwiftUI는 이러한 변경 사항을 자동으로 모니터링하고 데이터에 의존하는 모든 View의 body 속성을 다시 호출합니다.

참고자료

5. Adopt the Model Object in Your Views

(간단요약) step1 ~step7: 기존의 landmarks를 위에서 만들어준 ModelData().landmarks로 바꿔준다.

@EnvironmentObject 란?

@Environment라는 프로퍼티 래퍼는 읽기 전용 으로 특정 뷰에서 EnvironmentValues의 특정 요소를 읽어와 뷰 구성에 반영할 때 사용합니다.

참고자료

@StateObject란?

@StateObject 프로퍼티 래퍼는 겉보기엔 @ObservedObject와 비슷하게 작동합니다. 하지만 사용하는 것에는 명확한 차이점이 존재합니다. @StateObject를 통해서 관찰되고 있는 객체는 그들을 가지고 있는 화면 구조가 재생성되어도 파괴되지 않습니다.

참고자료

6. Create a Favorite Button for Each Landmark

(간단요약) step1 ~step7: 각 페이지 별로 즐겨찾기 버튼 만들기

  • @Binding을 사용하여 변수 만들어주고
    Binding이란?

    @State 로 선언된 속성을 다른 뷰에서 사용하려 한다면 @Binding 을 사용해 줄 수 있다. 사용시에는 앞에 $를 사용해 Bining 변수임을 나타낸다. @State 로 선언된 속성에 변경이 생기면 @Binding 변수에서 이를 인지하고 해당 값에 따른 뷰 변화를 바로 반영할 수 있도록 하는 방식입니다.

참고자료

  • FavoriteButton 만들어주기
struct FavoriteButton: View {
    @Binding var isSet: Bool
    
    var body: some View {
        Button {
            isSet.toggle()
        } label: {
            Label("Toggle Favorite",systemImage: isSet ? "star.fill" : "star")
                .labelStyle(.iconOnly)
                .foregroundColor(isSet ? .yellow : .gray)
        }
    }
}

깃헙 코드: https://github.com/LeeJoEun-01/SwiftUI-Study

profile
안녕하세요 개발 공부하는 joni 입니다 :)

0개의 댓글