Favor-Gift-Reminder / Favor-iOS

Favor(페이버) iOS 리포지토리
https://apps.apple.com/kr/app/favor-%ED%8E%98%EC%9D%B4%EB%B2%84/id6449257998
Apache License 2.0
3 stars 2 forks source link

[Feat] 디자인 변경점 적용 (메뉴 구성 변경) #112

Closed nomatterjun closed 1 year ago

nomatterjun commented 1 year ago

📋 설명

✅ 체크리스트

구현해야하는 이슈 체크리스트

  • [x] TabBar 변경
  • [x] 리마인더 접근 변경
nomatterjun commented 1 year ago

@eung7 이거 왜 이러는지 잘 모르겠는데 한 번 봐줄 수 있을까??

https://user-images.githubusercontent.com/60438045/230892141-992570c4-f709-4bde-9b67-30b70a48b09a.mp4

원래 두번 이동했는데 이때는 또 세번이나 가네;

스크린샷 2023-04-10 20 22 07

더보기(upcoming)나 필터(timeline) 버튼 누르면 출력하는 부분에서 각각 두번 씩 네번 출력되는 현상


일단 이 브랜치에서 작업한 내용을 설명해줄게

func navigateToDashBoard() -> FlowContributors {
  let homeFlow = HomeFlow()
  let myPageFlow = MyPageFlow()

  Flows.use(
    homeFlow,
    myPageFlow,
    when: .ready
  ) { [unowned self] (homeNC: BaseNavigationController, myPageNC: BaseNavigationController) in
    let pages = TabBarPage.allCases
    let emptyNC = BaseNavigationController()
    emptyNC.isValid = false // TabBarItem 클릭 가능 여부 파악을 위한 프로퍼티 설정
    let navigationControllers: [BaseNavigationController] = [homeNC, emptyNC, myPageNC]
    navigationControllers.enumerated().forEach { idx, nc in
      nc.tabBarItem = pages[idx].tabBarItem
    }

    self.rootViewController.setViewControllers(navigationControllers, animated: false)
  }

  return .multiple(flowContributors: [
    .contribute(
      withNextPresentable: homeFlow,
      withNextStepper: OneStepper(withSingleStep: AppStep.homeIsRequired)
    ),
    .contribute(withNext: self.rootViewController), // 빼면 TabBar에 위치한 Stepper가 없기 떄문에 NewGfitFlow로 present 불가능
    .contribute(
      withNextPresentable: myPageFlow,
      withNextStepper: OneStepper(withSingleStep: AppStep.myPageIsRequired)
    )
  ])
}

TabBar의 세 가지 메뉴 중에서 NewGfitpresent되는게 맞는 것 같아서 비어있는 NavigationController(자리를 만들기 위한 더미 뷰컨)를 넣어주고

func tabBarController(
  _ tabBarController: UITabBarController,
  shouldSelect viewController: UIViewController
) -> Bool {
  guard let navController = viewController as? BaseNavigationController else { return true }
  if !navController.isValid {
    self.steps.accept(AppStep.newGiftIsRequired)
    return false
  }
  return true
}

이렇게 선택되는 대신 Stepaccept하는 걸로 바꿔줬어

여기까진 오케이인데 저 모냥 저꼴이 된단 말이지


의심 1. DashboardFlow가 복제되었다?

.contribute(withNext: self.rootViewController) 이 부분 때문에 DashboardFlow가 두개가 돌고 있는 상황일지도.. 실제로 다른 Flow(SearchFlow)로 넘어갔다가 돌아와서 같은 동작을 수행시키면 횟수가 더 늘어나..

스크린샷 2023-04-10 20 55 57

근데 메모리 그래프 보니까 하나만 있긴 하네... 🤔 .contribute(withNext: self.rootViewController) 이 부분 주석 처리하고 실행해봤는데 그대로인거 보니까 이건 아닌가봐..

의심 2. 모든 HeaderViewAction이 트리거 됐다?

configureSupplementaryView: { dataSource, collectionView, kind, indexPath in
  let sectionItem = dataSource[indexPath.section]
  let header = collectionView.dequeueReusableSupplementaryView(
    ofKind: kind,
    for: indexPath) as HeaderView
  header.reactor = HeaderViewReactor(section: sectionItem.model)
  header.rx.rightButtonDidTap
    .map { Reactor.Action.rightButtonDidTap(sectionItem.model) }
    .bind(to: self.reactor!.action)
    .disposed(by: self.disposeBag)
  return header
}

이것도 bind로 처리해서 공유되는 스트림도 아닌데

case .rightButtonDidTap(let sectionType):
  let type = "\(sectionType)"
  os_log(.debug, "\(type)")
  switch sectionType {
  case .upcoming:
    self.steps.accept(AppStep.reminderIsRequired)
  case .timeline:
    self.steps.accept(AppStep.filterIsRequired(self.currentSortType.value))
  }
  return .empty()
}

여기 있는 os_log가 왜 네번이나 출력되는지도 모르겠네..


결론은 의심은 두 가지로 하고 있긴 한데 둘 다 원인이 아닐 가능성도 있어.. 애초에 두 번째 의심은 왜 발생하는지를 모르겠어 또 다른 이슈일지도..

같이 고민해줄 수 있겠니... 🤯

eung7 commented 1 year ago
image

내가 의심가는건 지금 dataSource 클로저의 configureSupplementaryView 가 여러번 구독되어서 발생하는 문제가 아닐까 싶어 내가 올려준 스크린샷에는 형이 구현한 화면에서 두 개의 헤더가 각각 두 번 생성이 되어서 총 4번의 스트림이 구독이 된 것 같아 그래서 형이 Home에서 스크롤의 바운스를 줄 때마다 configureSupplementaryView 또 불려서 새로운 스트림이 계속 만들어지는거지 그게 형이 말한 두번 -> 세번 -> 네번 Push 계속 늘어나는 것도 이 문제점인 것 같아!

일단 해결방안은 나도 지금 생각해보고 있어. 혹시 이상한 점 있으면 코멘트 남겨줘 !

nomatterjun commented 1 year ago

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ.... 응철아.. 찾았어.. 해결방법...... 하... 킹받아....

eung7 commented 1 year ago

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ....

응철아.. 찾았어.. 해결방법......

하... 킹받아....

뭔데?!

nomatterjun commented 1 year ago

너무 멍청한 실수라 헛웃음 밖에 안나오는 중...

header.rx.rightButtonDidTap
  .map { Reactor.Action.rightButtonDidTap(sectionItem.model) }
  .subscribe(onNext: {
    self.reactor!.action.onNext($0)
  })
  .disposed(by: self.disposeBag)

원래 이 코드였는데 여기서 self는 당연히 HomeVC잖아...? disposeHeaderViewreuse에 따라 동작해야하는데.. 그래서 self.disposeBag이 아니라 header.disposeBag으로 바꿔주면 subscribe가 해제되서 제대로 동작해..

header.rx.rightButtonDidTap
  .map { Reactor.Action.rightButtonDidTap(sectionItem.model) }
  .subscribe(onNext: {
    self.reactor!.action.onNext($0)
  })
  .disposed(by: header.disposeBag) // ⬅️ 이 부분