Skip to content

Conversation

@thingineeer
Copy link
Collaborator

@thingineeer thingineeer commented Nov 21, 2023

🌱 작업한 내용

  • 관련있는 부분 전체적으로 가독성 있게 코드 리팩터링 (구조 리팩터링 x)
  • 추천 코스(마라톤코스) 수평 스크롤 셀을 코스 발견에 추가 하였습니다.
  • 마라톤 코스 관련 네트워크 코드 추가 하였습니다 (DTO 추가)
  • 코스 전체 수를 가져와는 네트워크 코드 추가 하였습니다 (DTO 추가)
  • Cell 관리하는 부분 리팩터링을 진행 하였습니다. (Cell관련 Delegate 부분)
  • Combine 으로 이벤트 처리 코드 추가 ( 마라톤 Cell -> 코스 발견 뷰 에서 클릭 이벤트 처리)
  • 최신순, 스크랩순 버튼을 추가하였습니다.
    • default 최신순
  • 페이지 네이션 로직 살짝 변경

+12/5


+12/9

  • 코스 상세에서 스크랩 후, 코스 발견으로 이동할때 스크랩 부분 자연스럽게 변경
    • delegate 패턴 사용
      스크랩부분에 집중

코스 상세 -> 코스 발견 테스트 8
코스 발견 -> 코스 상세 테스트 5


🌱 PR Point

  • Enum을 활용하여 0...4로 되어있는 부분으로 상수화하였고, if~else문을 보기 좋게 Switch문으로 바꾸었습니다.
  • 마라톤 코스 발견 뷰는 따로 빼서 파일을 나눠 코드를 작성하였고, 코스 발견 뷰에 넣었습니다.
  • ⭐️⭐️ 페이지 네이션을 하는 과정 에서, 스크랩 부분을 어떻게 처리할지 고민입니다.
  • 업로드 버튼이 동적으로 바뀌는 과정에서 레이아웃(CGAffineTransform) 을 바꿀지, 그냥 isHidden을 번갈아가며 할지 고민을 하다 isHidden으로 해결하였는데, 추가 의견 있으시면 해당 부분에 리뷰 바랍니다.

레이아웃을 변동 시켰다면, 아래 예시 와 같은 코드가 될 것 입니다.

UIView.animate(withDuration: 0.5 {
    self.miniUploadButton.transform = .identity
    self.uploadButton.transform = CGAffineTransform(translationX: 0, y: 100)
}

UIView.animate(withDuration: 0.5 {
    self.uploadButton.transform = .identity
    self.miniUploadButton.transform = CGAffineTransform(translationX: 0, y: 100)
}

📸 스크린샷

구현 내용 스크린샷
코스발견

📮 관련 이슈

서버 API 연결 전 테스트 코드 입니다.
추천코스, 수평 스크롤 인점 감안하여 셀을 추가하였습니다. 이 부분은 추천코스의 역할을 할 예정입니다.
다양한 케이스가 매직넘버로 이루어져 있어, 상수로 대체하여 가독성을 증가시켰습니다.
TitleCollectionViewCell의 then으로 안된 문법을 변경해 주었습니다.
@thingineeer thingineeer added Feat 새로운 기능 구현 Refactor 전면 수정 labels Nov 21, 2023
@thingineeer thingineeer requested a review from 513sojin November 21, 2023 14:40
@thingineeer thingineeer self-assigned this Nov 21, 2023
@thingineeer thingineeer changed the title #194 - 코스 발견 페이지 UI 변경 하였습니다. [Feat] #194 - 코스 발견 페이지 UI 변경 하였습니다. Nov 21, 2023
추후 불필요한 메시지(코드) 삭제 예정
코스 발견 뷰로 넘겨줄 이벤트를 처리하기 위해 Combine을 사용하였습니다.
코스 발견에 넘어오는 이벤트를 처리하는 코드를 추가하였습니다.
함수의 코드의 복잡성이 있어, 따로 함수로 빼서 관리해 주게 짰습니다. 추후 저 셀도 따로 빼서 관리할 예정입니다.
getTotalPageCount 를 추가 하였습니다.
따로 데이터를 받는거라, 하나의 파라미터지만 DTO를 추가하였습니다.
getTotalPageNum() 함수를 추가하여 viewDidLoad 에 추가 해주었습니다.
Combine 으로 두번 호출되는 코드를 제거 하였습니다.
원래 빨리 내리거나, 너무 쭉 내리면 page 수가 너무 빨리 올라가 페이징이 의미가 없는 구현이 됐던 코드 입니다.
동기처리를 추가 하였고, 일부 pagination 로직 코드 수정을 하였습니다.
동기 처리를 await, task.sleep으로 가능하면 그걸로 할 예정
디버깅용 주석은 냅뒀습니다~
Copy link
Collaborator Author

@thingineeer thingineeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

모르는 거나, 궁금한 거, 이게 왜 있지? 하는 코드들이 있으면 전부 질문 남겨주세요
변수 명도 이상하거나, 이렇게 했으면 더 좋겠다 하는 것들도 전부요!!

Copy link
Collaborator

@513sojin 513sojin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

궁금한 부분 리뷰 남겨두었습니다!! 이번에도 많은 작업을 하셨네요 👍🏻

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 DTO는 언제 사용되는 건가요?!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서버에서 마라톤 코스를 따로 보내줄때 사용 됩니다 ‼️

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요거 ! @513sojin

image

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

struct TotalPageCountDto: Codable {
    let totalPageCount: Int
}

앗 요부분 말한거였어요 ㅎㅎ

Copy link
Collaborator Author

@thingineeer thingineeer Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@513sojin

아아 요 부분은 전체 페이지를 가져올 때 사용되는 DTO인데, 코스 불러올 때 전체 페이지가 달려오는 게 아니라 따로 호출해야 불러오기 때문에 DTO를 추가해 주었습니다!!

지금 코드에서는 주석 처리 해놔서 사용하지 않습니다.
주석 처리한 이유는 저희 앱스토어에 있는 서버(노드) 로 돌릴 때, totalCount를 주는 API가 없어서 그냥 테스트할 때는 상수로 해놓고 페이지 네이션 테스트 해놓고 있습니다! (참고로 저희 테섭은 1페이지당 10개 데이터로 바뀌었습니다, 노드는 24개씩)

image

let didSelectCourse = PassthroughSubject<IndexPath, Never>()
}

class MarathonMapCollectionViewCell: UICollectionViewCell {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 cell안에 collectionView가 들어가는 건가요 ..? 어떤 구조인지 궁금합니다

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞습니다.
코스 발견(collectionView) 수직 방향에
마라톤코스(collectionView) 수평 방향으로 Cell을 추가해주었습니다.

처음에 구현을 할 때, 코스 발견 안에서 코드를 구현하려고 하였습니다. (코스 발견의 맨 마지막 셀 이 원래 그 파일 안에 있던 것처럼)
하지만 코스 발견 내에서, 새로운 셀을 만들고 Cell 속성을 .horizontal 하여도 수평으로 스크롤이 되지 않은 문제에 직면하였습니다.
그래서 저는 마라톤 Cell이라는 파일을 따로 만들고 코스 발견 셀에 병합해 주는 코드를 작성을 하였습니다.

Copy link
Collaborator Author

@thingineeer thingineeer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이해 안 되는 거 있으면 몇 번이든 괜찮으니 댓글 달아주세요~ 👍

🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥
이 리뷰 아래는 제 댓글 밖에 안 보이니 위에 ⭐️질문한 곳⭐️ 에 필요한 댓글 달아주세요!
🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥🔥

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

서버에서 마라톤 코스를 따로 보내줄때 사용 됩니다 ‼️

let didSelectCourse = PassthroughSubject<IndexPath, Never>()
}

class MarathonMapCollectionViewCell: UICollectionViewCell {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞습니다.
코스 발견(collectionView) 수직 방향에
마라톤코스(collectionView) 수평 방향으로 Cell을 추가해주었습니다.

처음에 구현을 할 때, 코스 발견 안에서 코드를 구현하려고 하였습니다. (코스 발견의 맨 마지막 셀 이 원래 그 파일 안에 있던 것처럼)
하지만 코스 발견 내에서, 새로운 셀을 만들고 Cell 속성을 .horizontal 하여도 수평으로 스크롤이 되지 않은 문제에 직면하였습니다.
그래서 저는 마라톤 Cell이라는 파일을 따로 만들고 코스 발견 셀에 병합해 주는 코드를 작성을 하였습니다.

함수명 명명규칙 set ~~ 으로 변경 MarathonMapCVC 파일에서 "MarathonCourseListCVC" 를 "CourseListCVC" 으로 변경
구 버전 ic_plus_button 을 새 버전으로 변경 하였습니다.
UIScrollViewDelegate 로 따로 extension을 분리 해주었습니다.
적당한 스크롤 이벤트가 발생하면 업로드 버튼이 다르게 바뀌는 것을 구현하였습니다.
Copy link
Collaborator

@513sojin 513sojin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

답변 달아주신 부분 정독햇습니다 . 궁금증 해결완.
근데 보다보니 또 궁금한게 생겨서 질문 몇개 던져둡니다 ㅎㅎ

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

struct TotalPageCountDto: Codable {
    let totalPageCount: Int
}

앗 요부분 말한거였어요 ㅎㅎ

Comment on lines 389 to 396
private func handleButtonVisibility(uploadButtonChanged: Bool, hidden: Bool, miniHidden: Bool) {
guard self.uploadButtonChanged != uploadButtonChanged else {
return
}

toggleUploadButtons(hidden: hidden, miniHidden: miniHidden)
self.uploadButtonChanged = uploadButtonChanged
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

보다보니 이 부분도 궁금해졌습니다 ,, 이 부분은 어디 버튼 상태를 바꿔주는 함수인가요 ??!

Copy link
Collaborator Author

@thingineeer thingineeer Dec 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@513sojin

설명하기 전 새로 생긴 코드부터 설명하겠습니다.
파일 최상단에 위치해 있는 속성 부분에 private var uploadButtonChanged = false를 선언 한 이유는 scroll을 할 때마다 계속 업로드 버튼이 바뀌는 코드가 작동되다 보니, 자꾸 반짝반짝 거려서 한 번만 실행 시키기 위한 통제권 이라고 생각하시면 됩니다.

if contentOffsetY > scrollThreshold {
    handleButtonVisibility(uploadButtonChanged: true, hidden: true, miniHidden: false)
} else {
    handleButtonVisibility(uploadButtonChanged: false, hidden: false, miniHidden: true)
}

if contentOffsetY > scrollThreshold 일 경우 업로드 버튼이 사라지고, mini 업로드 버튼이 나타나는 코드이고,
반대 경우는 반대로 생각하시면 됩니다.

⭐️ 다시 본론으로 들어와 handleButtonVisibility 이 부분은 가시성을 위한 용도입니다.

changeButtonStyleOnScroll 메서드에서 contentOffsetYscrollThreshold를 기반으로 스크롤에 따라 버튼 가시성을 변경합니다. ‼️‼️ --> 일단 30% 정도 스크롤이 되었으면 바뀌게 설정 해두었어요.

그리고 handleButtonVisibility 메서드에서는 uploadButtonChanged변경되었을 때에만 버튼의 가시성을 조절하는 로직이 들어가 있습니다.
그 부분을 guard let 바인딩으로 해결 했구요 ‼️

private func handleButtonVisibility(uploadButtonChanged: Bool, hidden: Bool, miniHidden: Bool) {
    guard self.uploadButtonChanged != uploadButtonChanged else { return }
    {...중략... } 
}

마지막으로, toggleUploadButtons 메서드에서 버튼의 가시성을 변경하는 애니메이션을 수행하는 거죠 ‼

아래는 시연 영상입니다. (바뀌는 애니메이션은 아직 덜 공부하여 그나마 여러 개 해보다가 적당히 예쁜 걸로 했습니다 ^_^)
레이아웃과, 애니메이션은 추후 수정 예정입니다~ ‼️(아직 피그마에 확정이 안 남)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이해했습니다 !!!! 디테일한 부분까지 신경 많이쓰시네요 👍🏻
물어볼때마다 다 떠먹여주신 (.....) 덕분에 이번Pr에서 스크롤뷰쪽 개념 제대로 잡고 갑니다 수고하셨어요 !!@

@thingineeer thingineeer merged commit fd8cf56 into Runnect:develop Dec 9, 2023
@thingineeer thingineeer deleted the #194---코스-발견-페이지-UI-리뉴얼 branch December 9, 2023 15:23
@thingineeer thingineeer added the UX label Oct 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feat 새로운 기능 구현 Refactor 전면 수정 UX 명진😼

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] #194 - 코스 발견 페이지 UI 리뉴얼

2 participants