@@ -18,7 +18,7 @@ final class EmotionRegistrationViewController: BaseViewController<EmotionRegiste
1818 static let smallMarbleImageSize : CGFloat = 40
1919 static let emotionLabelWidth : CGFloat = 92
2020 static let emotionLabelHeight : CGFloat = 36
21- static let emotionCollectionViewHeight : CGFloat = 191
21+ static let emotionCollectionViewHeight : CGFloat = 291
2222 static let emotionMarbleImageViewSize : CGFloat = 140
2323 static let emotionMarbleImageViewTopSpacing : CGFloat = 13
2424 static let speechImageTopSpacing : CGFloat = 26
@@ -33,11 +33,12 @@ final class EmotionRegistrationViewController: BaseViewController<EmotionRegiste
3333 static let foromThumbLeadingSpacing : CGFloat = 71
3434 static let handMarbleImageViewBottomSpacing : CGFloat = 7
3535 static let handMarbleImageViewTopSpacing : CGFloat = 50
36- static let infoLabelTopSpacing : CGFloat = 30
36+ static let infoLabelTopSpacing : CGFloat = - 70
3737 static let doubleChevronIconSize : CGFloat = 24
3838 static let doubleChevronIconHorizontalSpacing : CGFloat = 26
3939 static let doubleChevronIconTopSpacing : CGFloat = 10
4040 static let infoViewSize : CGFloat = 0
41+ static let infoSwipeOverlayViewHeight = 100
4142 }
4243
4344 private let smallMarbleScrollView = UIScrollView ( )
@@ -55,14 +56,20 @@ final class EmotionRegistrationViewController: BaseViewController<EmotionRegiste
5556 private let leftDoubleChevronImageView = UIImageView ( )
5657 private let rightDoubleChevronImageView = UIImageView ( )
5758 private let downDoubleChevronImageView = UIImageView ( )
59+ private let infoSwipeOverlayView = UIView ( )
60+ private let hapticGenerator = UISelectionFeedbackGenerator ( )
61+ private let itemSetCount = 7
5862 private var isMarbleHeld = false
5963 private var marbleImageViewMidY : CGFloat ?
6064 private var marbleImageViewPanGesture : UIPanGestureRecognizer ?
65+ private var infoSwipeOverlayViewPanGesturePanGesture : UIPanGestureRecognizer ?
6166 private var emotion : Emotion ?
6267 private var dataSource : UICollectionViewDiffableDataSource < Int , Emotion > ?
6368 private var cancellables : Set < AnyCancellable >
69+ private var lastMarbleCellIndex : Int = 0
70+
6471 var itemCount : Int {
65- return ( dataSource? . snapshot ( ) . numberOfItems ?? 0 ) / 3
72+ return ( dataSource? . snapshot ( ) . numberOfItems ?? 0 ) / itemSetCount
6673 }
6774
6875
@@ -121,6 +128,10 @@ final class EmotionRegistrationViewController: BaseViewController<EmotionRegiste
121128 speechLabel. font = BitnagilFont . init ( style: . cafe24Title2, weight: . light) . font
122129 speechLabel. textColor = . clear
123130
131+ infoSwipeOverlayView. backgroundColor = . clear
132+ infoSwipeOverlayView. isUserInteractionEnabled = false
133+ infoSwipeOverlayView. backgroundColor = . clear
134+
124135 infoLabel. numberOfLines = 0
125136 infoLabel. font = BitnagilFont . init ( style: . body2, weight: . medium) . font
126137 infoLabel. textColor = BitnagilColor . gray50
@@ -160,6 +171,7 @@ final class EmotionRegistrationViewController: BaseViewController<EmotionRegiste
160171 view. addSubview ( handMarbleView)
161172 view. addSubview ( thumbImageView)
162173 view. addSubview ( infoView)
174+ view. addSubview ( infoSwipeOverlayView)
163175 smallMarbleScrollView. addSubview ( smallMarbleStackView)
164176 infoView. addSubview ( infoLabel)
165177 infoView. addSubview ( leftDoubleChevronImageView)
@@ -258,6 +270,12 @@ final class EmotionRegistrationViewController: BaseViewController<EmotionRegiste
258270 make. bottom. equalTo ( thumbImageView. snp. bottom) . offset ( - Layout. handMarbleImageViewBottomSpacing)
259271 make. size. equalTo ( Layout . emotionMarbleImageViewSize)
260272 }
273+
274+ infoSwipeOverlayView. snp. makeConstraints { make in
275+ make. horizontalEdges. equalToSuperview ( )
276+ make. bottom. equalTo ( emotionCollectionView. snp. bottom)
277+ make. height. equalTo ( Layout . infoSwipeOverlayViewHeight)
278+ }
261279 }
262280
263281 override func bind( ) {
@@ -267,11 +285,22 @@ final class EmotionRegistrationViewController: BaseViewController<EmotionRegiste
267285 guard let self = self else { return }
268286
269287 let originalEmotionCount = emotions. count
270- let tripledEmotions = emotions. map ( { $0. copy ( ) } ) + emotions + emotions. map ( { $0. copy ( ) } )
288+ let centerIndex = itemSetCount / 2 + 1
289+ let multipliedEmotions = ( 0 ..< 7 ) . flatMap { i in
290+ i == centerIndex ? emotions : emotions. map { $0. copy ( ) }
291+ }
292+
293+ guard
294+ let layout = emotionCollectionView. collectionViewLayout as? EmotionCollectionViewLayout ,
295+ let currentIndex = layout. fetchcurrentIndex ( )
296+ else { return }
297+
298+ lastMarbleCellIndex = currentIndex
299+ print ( lastMarbleCellIndex)
271300
272301 var snapshot = NSDiffableDataSourceSnapshot < Int , Emotion > ( )
273302 snapshot. appendSections ( [ 0 ] )
274- snapshot. appendItems ( tripledEmotions )
303+ snapshot. appendItems ( multipliedEmotions )
275304 self . dataSource? . apply ( snapshot, animatingDifferences: false )
276305
277306 self . scrollToIndex ( index: originalEmotionCount)
@@ -350,8 +379,7 @@ final class EmotionRegistrationViewController: BaseViewController<EmotionRegiste
350379 }
351380
352381 private func configureMarbleImageView( ) {
353- marbleImageViewPanGesture = UIPanGestureRecognizer ( target: self , action: #selector( handlePan ( gesture: ) ) )
354- marbleImageViewPanGesture? . cancelsTouchesInView = false
382+ marbleImageViewPanGesture = UIPanGestureRecognizer ( target: self , action: #selector( handleEmotionCollectionViewPanning ( gesture: ) ) )
355383
356384 handMarbleView. layer. cornerRadius = Layout . emotionMarbleImageViewSize / 2
357385 handMarbleView. layer. masksToBounds = true
@@ -377,7 +405,7 @@ final class EmotionRegistrationViewController: BaseViewController<EmotionRegiste
377405 }
378406 }
379407
380- @objc private func handlePan ( gesture: UIPanGestureRecognizer ) {
408+ @objc private func handleEmotionCollectionViewPanning ( gesture: UIPanGestureRecognizer ) {
381409 guard let marbleImageViewMidY else { return }
382410
383411 switch gesture. state {
@@ -454,8 +482,22 @@ extension EmotionRegistrationViewController: UICollectionViewDelegate {
454482}
455483
456484extension EmotionRegistrationViewController : UIScrollViewDelegate {
485+ func scrollViewDidScroll( _ scrollView: UIScrollView ) {
486+ guard
487+ let layout = emotionCollectionView. collectionViewLayout as? EmotionCollectionViewLayout ,
488+ let currentIndex = layout. fetchcurrentIndex ( ) ,
489+ lastMarbleCellIndex != currentIndex
490+ else { return }
491+
492+ lastMarbleCellIndex = currentIndex
493+ hapticGenerator. selectionChanged ( )
494+ hapticGenerator. prepare ( )
495+
496+ }
497+
457498 func scrollViewWillBeginDragging( _ scrollView: UIScrollView ) {
458499 emotionMarbleImageView. isHidden = true
500+ hapticGenerator. prepare ( )
459501 }
460502
461503 func scrollViewDidEndDecelerating( _ scrollView: UIScrollView ) {
@@ -470,7 +512,7 @@ extension EmotionRegistrationViewController: UIScrollViewDelegate {
470512 else { return }
471513
472514 let index = indexPath. row % itemCount
473- if indexPath. row < itemCount / 3 || indexPath. row >= itemCount * 2 / 3 {
515+ if indexPath. row < itemCount / itemSetCount || indexPath. row >= itemCount * ( itemSetCount / 2 + 1 ) / itemSetCount {
474516 scrollToIndex ( index: index)
475517 }
476518 viewModel. action ( input: . selectEmotion( index: index) )
0 commit comments