Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature/#77] 동영상 타임라인 드래그 앤 드롭 구현 #80

Merged
merged 12 commits into from
Dec 2, 2024

Conversation

LURKS02
Copy link
Collaborator

@LURKS02 LURKS02 commented Dec 2, 2024

관련 이슈

✅ 완료 및 수정 내역

  • DragDelegate, DropDelegate 구현
  • ViewModel과 초기화 로직 연결

🛠️ 테스트 방법

  • SharedVideoEditViewController를 루트로 하여 테스트 했습니다.

📝 리뷰 노트

ViewModel과 연결하면서 드롭 시 데이터 업데이트를 Input으로 보내 ViewModel에서 업데이트를 진행하려고 했으나 이 경우 애니메이션 오류가 발생합니다.

의도한 동작

drop을 통해 이동하려는 인덱스와 아이템 파악 -> 
ViewModel Input으로 전달 -> 
ViewModel transform에서 items 배열 조작 -> 
결과를 output으로 방출 -> 
output에 따른 컬렉션 뷰 반영 및 애니메이션

결과 동작

Simulator.Screen.Recording.-.iPhone.16.Pro.-.2024-12-02.at.16.30.46.mp4
drop으로 인한 애니메이션이 우선 진행 ->
이후 업데이트된 output에 대한 애니메이션 진행
(이런식으로 2번에 걸친 애니메이션이 발생하여 자연스럽게 보이지 않습니다.)

따라서 현재는 ViewModel을 통하지 않고 ViewController에서 직접 업데이트 합니다.
이 부분에서 어떻게 처리해야 할지? 조언이 필요합니다.


📱 스크린샷(선택)

Simulator.Screen.Recording.-.iPhone.16.Pro.-.2024-12-02.at.16.22.00.mp4

Copy link
Collaborator

@jungseokyoung-cloud jungseokyoung-cloud left a comment

Choose a reason for hiding this comment

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

고생하셨습니다!
사실 drag & drop이 View의 로직이기에 굳이 ViewModel로 이동할 필요는 없을꺼 같다는 생각입니다!
최종 결과물만 ViewModel로 넘겨주면 될꺼 같습니다!

@@ -7,7 +7,7 @@

import Foundation

public struct VideoTimelineItem: Hashable {
public struct VideoTimelineItem: Codable, Hashable {
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: 굳이 public일 이유가 있나요?

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

Choose a reason for hiding this comment

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

�제가 다른 코드 구현할 때 ViewModelOutput에서 직접 Item을 건네주기 때문에 이렇게 따라서 구현하신 것 같긴 한데 우선 사용되는 부분은 없으니 수정해두겠습니다!

@@ -7,4 +7,6 @@

import Foundation

enum SharedVideoEditViewInput { }
enum SharedVideoEditViewInput {
case initialize
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: initialize말고 좀더 명확한 네이밍이 있었으면 함다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

setInitialState 로 바꿨습니다.

@@ -15,13 +15,43 @@ public final class SharedVideoEditViewModel {

private var output = PassthroughSubject<Output, Never>()
private var cancellables: Set<AnyCancellable> = []

var items: [VideoTimelineItem] = []
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: 이친구는 왜 Internal인가요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

지금 뷰모델 구조에서 state를 직접 꺼내올 수 있는 방법을 못찾았습니다. 따라서 ViewModel이 items를 internal로 가지고 있게 됩니다.


public init() {
setupBind()
}

func transform(_ input: AnyPublisher<Input, Never>) -> AnyPublisher<Output, Never> {
input.sink { _ in
input.sink { [weak self] input in
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: 제가 Core에 sink(with:onReceive:) 메서드 추가해놨습니다! 사용하시면 [weak self] 안쓰셔도됩니다!
이전 SliderBar PR에 내용 올려두신 했었슴다


coordinator.items.forEach { item in
if let sourceIndexPath = item.sourceIndexPath {
collectionView.performBatchUpdates({
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: 여기는 개인적으로 DIffabledataSource를 사용해보면 어떨까 싶긴 합니다~!

@@ -80,7 +80,11 @@ private extension SharedVideoEditViewController {

output
.receive(on: DispatchQueue.main)
.sink { output in
.sink { [weak self] output in
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: 이것도 Core의 sink(with:onReceive:)사용하시면 편하게 사용하실 수 있습니다!

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

@around-forest around-forest left a comment

Choose a reason for hiding this comment

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

고생하셨습니다!
저도 석영님 생각처럼 ViewModel로 이동할 필요는 없다 생각합니다.

var items = viewModel.items
let movedItem = items.remove(at: sourceIndexPath.item)
items.insert(movedItem, at: destinationIndexPath.item)
viewModel.items = items
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: ViewModel의 property에 직접 접근하기보다 메서드를 통해 접근하는게 더 낫지 않을까 싶네요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

getItems() 같은 형태를 따로 만들자는 말씀이신가요??

@@ -16,3 +16,18 @@ public struct VideoTimelineItem: Hashable {
hasher.combine(identifier)
}
}

extension VideoTimelineItem {
static func fromJSONString(_ jsonString: String) -> VideoTimelineItem? {
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: func toVideoTimelineItem(from jsonString: String) 이면 보다 명확하지 않을까 싶긴 합니다.

Copy link
Collaborator

Choose a reason for hiding this comment

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

@around-forest static func여서 호출할 때 중복되는 부분이 많아질 것 같아요

VideoTimelineItem.toVideoTimelineItem("lipsum")

P3: String 대신 Data 타입은 어떤가 싶습니다만 아무래도 상관없을 것 같습니다

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

저도 윤회님 의견과 동일하고 Data로 바꾸는 것도 좋아보이네요!

input.sink { [weak self] input in
guard let self else { return }
switch input {
case .initialize:
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: 테스트용 코드는 주석을 넣어주세요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

수정했습니다!

@@ -7,4 +7,6 @@

import Foundation

enum SharedVideoEditViewOutput { }
enum SharedVideoEditViewOutput {
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: 개인적으로 InputOutput은 하나의 파일로 합쳐도 되지 않을까 싶긴한데... 이야기 해보면 좋겠네요!

Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: 특별한 이유가 없다면 파일을 구분하자는 편 입니다.
입출력은 별도의 역할이기도 하고, 종류가 많아진다면 구분할 필요가 생길 것 같아요.
그리고 파일로 구분하는 비용이 그렇지 않을 때 보다 높지 않기도 하구요

Copy link
Collaborator

@051198Hz 051198Hz left a comment

Choose a reason for hiding this comment

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

고생많으셨습니다~!
단순 궁금증인데 드래그&드롭을 ViewModel과 ViewContorller에서 처리하는게 어떤 차이가 있어서 애니메이션이 이상해지는지 궁금하네요! 뷰컨에서는 DataSourcr를 업데이트하는 구조를 다르게 가져갈 수 있는 건가요?

@@ -7,7 +7,7 @@

import Foundation

public struct VideoTimelineItem: Hashable {
public struct VideoTimelineItem: Codable, Hashable {
Copy link
Collaborator

Choose a reason for hiding this comment

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

동일한 의견입니다~

@@ -16,3 +16,18 @@ public struct VideoTimelineItem: Hashable {
hasher.combine(identifier)
}
}

extension VideoTimelineItem {
static func fromJSONString(_ jsonString: String) -> VideoTimelineItem? {
Copy link
Collaborator

Choose a reason for hiding this comment

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

@around-forest static func여서 호출할 때 중복되는 부분이 많아질 것 같아요

VideoTimelineItem.toVideoTimelineItem("lipsum")

P3: String 대신 Data 타입은 어떤가 싶습니다만 아무래도 상관없을 것 같습니다

@@ -7,4 +7,6 @@

import Foundation

enum SharedVideoEditViewOutput { }
enum SharedVideoEditViewOutput {
Copy link
Collaborator

Choose a reason for hiding this comment

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

P2: 특별한 이유가 없다면 파일을 구분하자는 편 입니다.
입출력은 별도의 역할이기도 하고, 종류가 많아진다면 구분할 필요가 생길 것 같아요.
그리고 파일로 구분하는 비용이 그렇지 않을 때 보다 높지 않기도 하구요

@LURKS02 LURKS02 merged commit e84ffd8 into develop Dec 2, 2024
1 check passed
@LURKS02 LURKS02 deleted the feature/#77 branch December 2, 2024 13:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants