-
Notifications
You must be signed in to change notification settings - Fork 1
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
Conversation
- 선택한 아이템을 JSONString으로 변환하여 UIDragItem으로 사용
- 드롭 시 items를 업데이트하고 반영하여 리로드를 진행
There was a problem hiding this 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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: 굳이 public일 이유가 있나요?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
동일한 의견입니다~
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: initialize
말고 좀더 명확한 네이밍이 있었으면 함다!
There was a problem hiding this comment.
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] = [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: 이친구는 왜 Internal인가요??
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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({ |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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:)
사용하시면 편하게 사용하실 수 있습니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
수정했습니다~!
There was a problem hiding this 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: ViewModel의 property에 직접 접근하기보다 메서드를 통해 접근하는게 더 낫지 않을까 싶네요!
There was a problem hiding this comment.
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? { |
There was a problem hiding this comment.
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)
이면 보다 명확하지 않을까 싶긴 합니다.
There was a problem hiding this comment.
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 타입은 어떤가 싶습니다만 아무래도 상관없을 것 같습니다
There was a problem hiding this comment.
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: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: 테스트용 코드는 주석을 넣어주세요!
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: 개인적으로 InputOutput은 하나의 파일로 합쳐도 되지 않을까 싶긴한데... 이야기 해보면 좋겠네요!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: 특별한 이유가 없다면 파일을 구분하자는 편 입니다.
입출력은 별도의 역할이기도 하고, 종류가 많아진다면 구분할 필요가 생길 것 같아요.
그리고 파일로 구분하는 비용이 그렇지 않을 때 보다 높지 않기도 하구요
There was a problem hiding this 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 { |
There was a problem hiding this comment.
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? { |
There was a problem hiding this comment.
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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2: 특별한 이유가 없다면 파일을 구분하자는 편 입니다.
입출력은 별도의 역할이기도 하고, 종류가 많아진다면 구분할 필요가 생길 것 같아요.
그리고 파일로 구분하는 비용이 그렇지 않을 때 보다 높지 않기도 하구요
관련 이슈
✅ 완료 및 수정 내역
🛠️ 테스트 방법
📝 리뷰 노트
ViewModel과 연결하면서 드롭 시 데이터 업데이트를 Input으로 보내 ViewModel에서 업데이트를 진행하려고 했으나 이 경우 애니메이션 오류가 발생합니다.
의도한 동작
결과 동작
Simulator.Screen.Recording.-.iPhone.16.Pro.-.2024-12-02.at.16.30.46.mp4
따라서 현재는 ViewModel을 통하지 않고 ViewController에서 직접 업데이트 합니다.
이 부분에서 어떻게 처리해야 할지? 조언이 필요합니다.
📱 스크린샷(선택)
Simulator.Screen.Recording.-.iPhone.16.Pro.-.2024-12-02.at.16.22.00.mp4