TCA

iOS 17 ์•„๋ž˜ ๋ฒ„์ „

@Bindable ์€ iOS 17 ์ดํ›„๋กœ ์ œ๊ณต

@ObservableState ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” @Perception.Bindable ๋กœ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

์ถ”๊ฐ€๋กœ WithPerceptionTracking ๋ฅผ ํ•ด์•ผ ์ •์ƒ ๋™์ž‘ํ•œ๋‹ค.

Action์—๋„ @CasePathable ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•œ๋‹ค.

struct RootView: View {
  
  @Perception.Bindable
  private var store: StoreOf<RootFeature>
  
  init(store: StoreOf<RootFeature>) {
    self.store = store
  }
  
  var body: some View {
    WithPerceptionTracking {
      TabView(selection: $store.selectedTab.sending(\.tabSelected)) {
        HomeView(store: store.scope(state: \.home, action: \.home))
          .tabItem { Text(RootTab.home.title) }
          .tag(RootTab.home)
        
        FeedView(store: store.scope(state: \.feed, action: \.feed))
          .tabItem { Text(RootTab.feed.title) }
          .tag(RootTab.feed)
        
        TodayView(store: store.scope(state: \.today, action: \.today))
          .tabItem { Text(RootTab.today.title) }
          .tag(RootTab.today)
        
        MyView(store: store.scope(state: \.my, action: \.my))
          .tabItem { Text(RootTab.my.title) }
          .tag(RootTab.my)
      }
    }
  }
  
}

@Reducer
struct RootFeature {
  
  @ObservableState
  struct State: Equatable {
    var selectedTab: RootTab = .home
    var home: HomeFeature.State = .init()
    var feed: FeedFeature.State = .init()
    var today: TodayFeature.State = .init()
    var my: MyFeature.State = .init()
  }
  
  @CasePathable
  enum Action {
    case home(HomeFeature.Action)
    case feed(FeedFeature.Action)
    case today(TodayFeature.Action)
    case my(MyFeature.Action)
    
    case tabSelected(RootTab)
  }
  
  var body: some ReducerOf<Self> {
    Scope(state: \.home, action: \.home) {
      HomeFeature()
    }
    
    Scope(state: \.feed, action: \.feed) {
      FeedFeature()
    }
    
    Scope(state: \.today, action: \.today) {
      TodayFeature()
    }
    
    Scope(state: \.my, action: \.my) {
      MyFeature()
    }
    
    Reduce { state, action in
      switch action {
      case .home, .feed, .today, .my:
        return .none
        
      case let .tabSelected(selectedTab):
        state.selectedTab = selectedTab
        return .none
      }
    }
  }
  
}

GeometryReader ๋‚ด๋ถ€๋„ WithPerceptionTracking๋กœ ๊ฐ์‹ธ์•ผ ํ•œ๋‹ค

์™ธ๋ถ€ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ GeometryReader๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๋‚ด๋ถ€์—๋„ ๊ฐ์‹ธ์•ผ ํ•จ

Last updated