Skip to content

Commit 8b91956

Browse files
committed
[#74]Feat: 좋아요 버튼 액션 구현
- TimeState에 none 케이스 생성 - 좋아요, 싫어요, 신고, 차단 시, 타이머, 프로그래스를 초기화하기 위함 - 13초에서 15초로 디자인 반영 - vc에서는 scroll만 처리하고 나머지는 cell에서 처리할 수 있도록 구현
1 parent 06d0a47 commit 8b91956

File tree

4 files changed

+83
-69
lines changed

4 files changed

+83
-69
lines changed

Projects/Features/Falling/Src/Home/FallingHomeViewController.swift

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import DSKit
1212
import FallingInterface
1313

1414
enum FallingCellButtonAction {
15-
case info(IndexPath)
1615
case reject(IndexPath)
1716
case like(IndexPath)
1817
}
@@ -121,7 +120,7 @@ final class FallingHomeViewController: TFBaseViewController {
121120
}
122121

123122
let footerRegistration = UICollectionView.SupplementaryRegistration
124-
<UICollectionReusableView>(elementKind: UICollectionView.elementKindSectionFooter) { _,_,_ in }
123+
<DummyFooterView>(elementKind: UICollectionView.elementKindSectionFooter) { _,_,_ in }
125124

126125
dataSource = DataSource(collectionView: homeView.collectionView, cellProvider: { collectionView, indexPath, itemIdentifier in
127126
return collectionView.dequeueConfiguredReusableCell(using: profileCellRegistration, for: indexPath, item: itemIdentifier)
@@ -156,21 +155,16 @@ final class FallingHomeViewController: TFBaseViewController {
156155
})
157156
.disposed(by: self.disposeBag)
158157

159-
output.infoButtonAction
160-
.drive(with: self) { owner, indexPath in
161-
guard let cell = owner.homeView.collectionView.cellForItem(at: indexPath) as? FallingUserCollectionViewCell
162-
else { return }
163-
cell.userInfoView.isHidden.toggle()
158+
output.likeButtonAction
159+
.drive(with: self) { owner, _ in
160+
DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
161+
timeOverSubject.onNext(.scroll)
162+
}
164163
}
165164
.disposed(by: disposeBag)
166165

167166
output.rejectButtonAction
168-
.drive(with: self) { owner, indexPath in
169-
guard let cell = owner.homeView.collectionView.cellForItem(at: indexPath) as? FallingUserCollectionViewCell else { return }
170-
171-
cell.rejectLottieView.isHidden = false
172-
cell.rejectLottieView.play()
173-
167+
.drive(with: self) { owner, _ in
174168
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
175169
timeOverSubject.onNext(.scroll)
176170
}

Projects/Features/Falling/Src/Home/FallingHomeViewModel.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ final class FallingHomeViewModel: ViewModelType {
3131
struct Output {
3232
let userList: Driver<[FallingUser]>
3333
let nextCardIndexPath: Driver<IndexPath>
34-
let infoButtonAction: Driver<IndexPath>
34+
let likeButtonAction: Driver<IndexPath>
3535
let rejectButtonAction: Driver<IndexPath>
3636
let complaintsAction: Driver<IndexPath>
3737
let blockAction: Driver<IndexPath>
@@ -74,11 +74,12 @@ final class FallingHomeViewModel: ViewModelType {
7474
).withLatestFrom(currentIndexRelay.asDriver(onErrorJustReturn: 0)
7575
.map { IndexPath(row: $0, section: 0) })
7676

77-
let infoButtonAction = input.cellButtonAction
77+
let likeButtonAction = input.cellButtonAction
7878
.compactMap { action -> IndexPath? in
79-
if case let .info(indexPath) = action {
79+
if case let .like(indexPath) = action {
8080
return indexPath
81-
} else { return nil }
81+
}
82+
return nil
8283
}
8384

8485
let rejectButtonAction = input.cellButtonAction
@@ -107,7 +108,7 @@ final class FallingHomeViewModel: ViewModelType {
107108
return Output(
108109
userList: userList,
109110
nextCardIndexPath: nextCardIndexPath,
110-
infoButtonAction: infoButtonAction,
111+
likeButtonAction: likeButtonAction,
111112
rejectButtonAction: rejectButtonAction,
112113
complaintsAction: complaintsAction,
113114
blockAction: blockAction

Projects/Features/Falling/Src/Subviews/Cell/FallingUserCollectionViewCell.swift

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,9 +57,8 @@ final class FallingUserCollectionViewCell: TFBaseCollectionViewCell {
5757
return pauseView
5858
}()
5959

60-
lazy var rejectLottieView: LottieAnimationView = {
60+
lazy var lottieView: LottieAnimationView = {
6161
let lottieAnimationView = LottieAnimationView()
62-
lottieAnimationView.animation = AnimationAsset.unlike.animation
6362
lottieAnimationView.isHidden = true
6463
lottieAnimationView.contentMode = .scaleAspectFit
6564
return lottieAnimationView
@@ -77,7 +76,7 @@ final class FallingUserCollectionViewCell: TFBaseCollectionViewCell {
7776
override func makeUI() {
7877
self.layer.cornerRadius = 20
7978

80-
self.contentView.addSubviews([profileCollectionView, cardTimeView, userInfoBoxView, userInfoBoxView, userInfoView, rejectLottieView, pauseView])
79+
self.contentView.addSubviews([profileCollectionView, cardTimeView, userInfoBoxView, userInfoBoxView, userInfoView, lottieView, pauseView])
8180

8281
profileCollectionView.snp.makeConstraints {
8382
$0.edges.equalToSuperview()
@@ -104,7 +103,7 @@ final class FallingUserCollectionViewCell: TFBaseCollectionViewCell {
104103
$0.edges.equalToSuperview()
105104
}
106105

107-
self.rejectLottieView.snp.makeConstraints {
106+
self.lottieView.snp.makeConstraints {
108107
$0.center.equalToSuperview()
109108
$0.width.height.equalTo(188) // TODO: 사이즈 수정 예정
110109
}
@@ -130,7 +129,7 @@ final class FallingUserCollectionViewCell: TFBaseCollectionViewCell {
130129
) where O: ObserverType, O.Element == FallingCellButtonAction {
131130
let infoButtonTapTrigger = userInfoBoxView.infoButton.rx.tap.asDriver()
132131

133-
let rejectButtonTapTrigger = userInfoBoxView.rejectButton.rx.tap.mapToVoid().asDriverOnErrorJustEmpty()
132+
let rejectButtonTapTrigger = userInfoBoxView.rejectButton.rx.tap.asDriver()
134133

135134
let likeButtonTapTrigger = userInfoBoxView.likeButton.rx.tap.asDriver()
136135

@@ -196,13 +195,28 @@ final class FallingUserCollectionViewCell: TFBaseCollectionViewCell {
196195
output.rejectButtonAction
197196
.compactMap { [weak self] _ in self?.indexPath }
198197
.map { FallingCellButtonAction.reject($0) }
199-
.drive(fallingCellButtonAction)
198+
.drive(with: self) { owner, action in
199+
fallingCellButtonAction.onNext(action)
200+
owner.lottieView.snp.updateConstraints { $0.width.height.equalTo(188) }
201+
owner.lottieView.animation = AnimationAsset.unlike.animation
202+
owner.lottieView.isHidden = false
203+
owner.lottieView.play()
204+
}
200205
.disposed(by: disposeBag)
201206

202207
output.likeButtonAction
203208
.compactMap { [weak self] _ in self?.indexPath }
204209
.map { FallingCellButtonAction.like($0) }
205-
.drive(fallingCellButtonAction)
210+
.drive(with: self) { owner, action in
211+
fallingCellButtonAction.onNext(action)
212+
owner.lottieView.snp.updateConstraints { $0.width.height.equalTo(200) }
213+
owner.lottieView.animation = AnimationAsset.likeHeart.animation
214+
owner.lottieView.isHidden = false
215+
owner.lottieView.play()
216+
owner.cardTimeView.progressView.addGradientLayer()
217+
owner.cardTimeView.timerView.timerLabel.isHidden = true
218+
owner.cardTimeView.timerView.addGradientLayer()
219+
}
206220
.disposed(by: disposeBag)
207221

208222
output.reportButtonAction
@@ -270,7 +284,7 @@ extension FallingUserCollectionViewCell {
270284
extension Reactive where Base: FallingUserCollectionViewCell {
271285
var timeState: Binder<TimeState> {
272286
return Binder(self.base) { (base, timeState) in
273-
base.cardTimeView.timerView.trackLayer.strokeColor = timeState.fillColor.color.cgColor
287+
base.cardTimeView.timerView.trackLayer.strokeColor = timeState.trackLayerStrokeColor.color.cgColor
274288
base.cardTimeView.timerView.strokeLayer.strokeColor = timeState.timerTintColor.color.cgColor
275289
base.cardTimeView.timerView.dotLayer.strokeColor = timeState.timerTintColor.color.cgColor
276290
base.cardTimeView.timerView.dotLayer.fillColor = timeState.timerTintColor.color.cgColor

Projects/Features/Falling/Src/Subviews/Cell/FallinguserCollectionViewCellModel.swift

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,25 +12,27 @@ import FallingInterface
1212
import DSKit
1313

1414
enum TimeState {
15-
case initial(value: Double) // 12~13
16-
case five(value: Double) // 10~12
17-
case four(value: Double) // 8~10
18-
case three(value: Double) // 6~8
19-
case two(value: Double) // 4~6
20-
case one(value: Double) // 2~4
21-
case zero(value: Double) // 1~2
22-
case over(value: Double) // 0~1
15+
case initial(value: Double) // 14~15
16+
case five(value: Double) // 12~14
17+
case four(value: Double) // 10~12
18+
case three(value: Double) // 8~10
19+
case two(value: Double) // 6~8
20+
case one(value: Double) // 4~6
21+
case zero(value: Double) // 2~4
22+
case over(value: Double) // 0~2
23+
case none // Reject(싫어요) or Like(좋아요) or Delete(신고, 차단) user
2324

2425
init(rawValue: Double) {
2526
switch rawValue {
26-
case 12.0..<13.0: self = .initial(value: rawValue)
27-
case 10.0..<12.0: self = .five(value: rawValue)
28-
case 8.0..<10.0: self = .four(value: rawValue)
29-
case 6.0..<8.0: self = .three(value: rawValue)
30-
case 4.0..<6.0: self = .two(value: rawValue)
31-
case 2.0..<4.0: self = .one(value: rawValue)
32-
case 1.0..<2.0: self = .zero(value: rawValue)
33-
default: self = .over(value: rawValue)
27+
case 14.0..<15.0: self = .initial(value: rawValue)
28+
case 12.0..<14.0: self = .five(value: rawValue)
29+
case 10.0..<12.0: self = .four(value: rawValue)
30+
case 8.0..<10.0: self = .three(value: rawValue)
31+
case 6.0..<8.0: self = .two(value: rawValue)
32+
case 4.0..<6.0: self = .one(value: rawValue)
33+
case 2.0..<4.0: self = .zero(value: rawValue)
34+
case 0.0..<2.0: self = .over(value: rawValue)
35+
default: self = .none
3436
}
3537
}
3638

@@ -58,43 +60,44 @@ enum TimeState {
5860

5961
var isDotHidden: Bool {
6062
switch self {
61-
case .initial, .over: return true
63+
case .initial, .over, .none: return true
6264
default: return false
6365
}
6466
}
6567

66-
var fillColor: DSKitColors {
68+
var trackLayerStrokeColor: DSKitColors {
6769
switch self {
68-
case .over: return DSKitAsset.Color.neutral300
70+
case .initial, .over, .none: return DSKitAsset.Color.neutral300
6971
default: return DSKitAsset.Color.clear
7072
}
7173
}
7274

7375
var getText: String {
7476
switch self {
75-
case .initial, .over: return "-"
7677
case .five: return "5"
7778
case .four: return "4"
7879
case .three: return "3"
7980
case .two: return "2"
8081
case .one: return "1"
8182
case .zero: return "0"
83+
default: return "-"
8284
}
8385
}
8486

8587
var getProgress: Double {
8688
switch self {
8789
case .initial: return 1
8890
case .five(let value), .four(let value), .three(let value), .two(let value), .one(let value), .zero(let value), .over(let value):
89-
return round((value / 2 - 1) / 5 * 1000) / 1000
91+
return round((value / 2 - 2) / 5 * 1000) / 1000
92+
default: return 0
9093
}
9194
}
9295
}
9396

9497
final private class Timer {
9598
private var disposable: Disposable? = nil
9699

97-
let currentTime = BehaviorRelay<Double>(value: 13.0)
100+
let currentTime = BehaviorRelay<Double>(value: 15.0)
98101
private var startTime: Double
99102

100103
init(startTime: Double) {
@@ -103,7 +106,7 @@ final private class Timer {
103106

104107
func start() {
105108
guard disposable == nil else { return }
106-
if startTime < 0 { startTime = 13.0 }
109+
if startTime < 0 { startTime = 15.0 }
107110

108111
disposable = Observable<Int>.interval(.milliseconds(10),
109112
scheduler: MainScheduler.instance)
@@ -144,8 +147,8 @@ final class FallingUserCollectionViewCellModel: ViewModelType {
144147
struct Output {
145148
let user: Driver<FallingUser>
146149
let timeState: Driver<TimeState>
147-
let timeZero: Driver<AnimationAction>
148150
let timerActiveAction: Driver<Bool>
151+
let timeZero: Driver<AnimationAction>
149152
let rejectButtonAction: Driver<Void>
150153
let likeButtonAction: Driver<Void>
151154
let showUserInfoAction: Driver<Bool>
@@ -154,20 +157,18 @@ final class FallingUserCollectionViewCellModel: ViewModelType {
154157
}
155158

156159
func transform(input: Input) -> Output {
157-
let timer = Timer(startTime: 13.0)
158-
let user = Driver.just(self.userDomain)
159-
160-
let timerActiveTrigger = input.timerActiveTrigger
161-
162-
let rejectButtonAction = input.rejectButtonTapTrigger
163-
.do(onNext: { _ in
164-
timer.pause()
165-
timer.currentTime.accept(-1.0) // reject 시에는 0.5초 후에 넘어 가야하는 제약이 있어서, 0초로 설정하지 않았고, reject 버튼 이벤트에 대한 처리는 상위 뷰에서 따로 처리하고 있음.
166-
})
160+
let timer = Timer(startTime: 15.0)
161+
let time = timer.currentTime.asDriver(onErrorJustReturn: 0.0)
162+
let user = Driver.just(userDomain)
167163

168-
let likeButtonAction = input.likeButtonTapTrigger
164+
let timeState = Driver.merge(
165+
input.rejectButtonTapTrigger.map { TimeState.none },
166+
input.likeButtonTapTrigger.map { TimeState.none },
167+
input.deleteCellTrigger.map { TimeState.none },
168+
time.map { TimeState(rawValue: $0) }
169+
)
169170

170-
let timeActiveAction = timerActiveTrigger
171+
let timerActiveAction = input.timerActiveTrigger
171172
.do { value in
172173
if !value {
173174
timer.pause()
@@ -176,12 +177,17 @@ final class FallingUserCollectionViewCellModel: ViewModelType {
176177
}
177178
}
178179

179-
let time = timer.currentTime.asDriver(onErrorJustReturn: 0.0)
180-
181-
let timeState = time.map { TimeState(rawValue: $0) }
182180
let timeZero = time.filter { $0 == 0.0 }.flatMapLatest { _ in Driver.just(AnimationAction.scroll) }
183-
let timerActiveAction = timeActiveAction.asDriver(onErrorJustReturn:
184-
true)
181+
182+
let rejectButtonAction = input.rejectButtonTapTrigger
183+
.do { _ in
184+
timer.pause()
185+
}
186+
187+
let likeButtonAction = input.likeButtonTapTrigger
188+
.do { _ in
189+
timer.pause()
190+
}
185191

186192
let showUserInfoAction = input.showUserInfoTrigger
187193

@@ -190,14 +196,13 @@ final class FallingUserCollectionViewCellModel: ViewModelType {
190196
let deleteCellAction = input.deleteCellTrigger
191197
.do(onNext: {
192198
timer.pause()
193-
timer.currentTime.accept(-1.0)
194199
})
195200

196201
return Output(
197202
user: user,
198203
timeState: timeState,
199-
timeZero: timeZero,
200204
timerActiveAction: timerActiveAction,
205+
timeZero: timeZero,
201206
rejectButtonAction: rejectButtonAction,
202207
likeButtonAction: likeButtonAction,
203208
showUserInfoAction: showUserInfoAction,

0 commit comments

Comments
 (0)