Skip to content

Commit e85983f

Browse files
committed
feat: CameraViewController ZoomView Button으로 수정
- CameraViewController TransitionZoomImageScale, TransitionPinchImageScale Method 추가 - pinchZoomScale, zooScale Binding 코드 추가 or didTapZoomButton, dragPreviewLayer Action 추가 - CameraViewReactor didTapZoomButton, dragPreviewLayer Action, setPinchZoomScale, setZoomScale Mutation 추가 - DesignSystem Assets zoomOut 이미지 추가
1 parent efcf46b commit e85983f

File tree

6 files changed

+103
-30
lines changed

6 files changed

+103
-30
lines changed

14th-team5-iOS/App/Sources/Presentation/Camera/CameraViewController.swift

+59-29
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public final class CameraViewController: BaseViewController<CameraViewReactor> {
3636
private let toggleButton: UIButton = UIButton.createCircleButton(radius: 24)
3737
private let cameraIndicatorView: BibbiLoadingView = BibbiLoadingView()
3838
private let filterView: UIImageView = UIImageView()
39-
private let zoomView: UIImageView = UIImageView()
39+
private let zoomView: UIButton = UIButton()
4040
private let realEmojiDescriptionLabel = BibbiLabel(.body1Regular, textColor: .mainYellow)
4141
private let realEmojiFaceView = UIView()
4242
private let realEmojiFaceImageView = UIImageView()
@@ -71,7 +71,7 @@ public final class CameraViewController: BaseViewController<CameraViewReactor> {
7171
public override func setupUI() {
7272
super.setupUI()
7373
realEmojiFaceView.addSubview(realEmojiFaceImageView)
74-
view.addSubviews(cameraView, shutterButton, flashButton, toggleButton, realEmojiFaceView, realEmojiHorizontalStakView, realEmojiCollectionView, cameraIndicatorView , cameraNavigationBar)
74+
view.addSubviews(cameraView, shutterButton, flashButton, toggleButton, realEmojiFaceView, realEmojiHorizontalStakView, realEmojiCollectionView ,cameraIndicatorView , cameraNavigationBar)
7575
}
7676

7777
public override func setupAttributes() {
@@ -87,8 +87,8 @@ public final class CameraViewController: BaseViewController<CameraViewReactor> {
8787
}
8888

8989
zoomView.do {
90-
$0.image = DesignSystemAsset.zoom.image
91-
$0.contentMode = .scaleAspectFill
90+
$0.setBackgroundImage(DesignSystemAsset.zoomin.image, for: .normal)
91+
$0.setTitle("", for: .normal)
9292
}
9393

9494
realEmojiFlowLayout.do {
@@ -276,6 +276,41 @@ public final class CameraViewController: BaseViewController<CameraViewReactor> {
276276
NotificationCenter.default.post(name: .DidFinishProfileImageUpdate, object: nil, userInfo: userInfo)
277277
}.disposed(by: disposeBag)
278278

279+
zoomView
280+
.rx.tap
281+
.map { _ in CGFloat(1.0)}
282+
.map { Reactor.Action.didTapZoomButton($0)}
283+
.bind(to: reactor.action)
284+
.disposed(by: disposeBag)
285+
286+
reactor.pulse(\.$zoomScale)
287+
.withUnretained(self)
288+
.observe(on: MainScheduler.instance)
289+
.bind(onNext: {
290+
guard let currentCamera = $0.0.isToggle ? $0.0.frontCamera : $0.0.backCamera else { return }
291+
$0.0.transitionZoomImageScale(owner: $0.0, scale: $0.1, camera: currentCamera)
292+
}).disposed(by: disposeBag)
293+
294+
reactor.pulse(\.$pinchZoomScale)
295+
.withUnretained(self)
296+
.bind(onNext: {
297+
guard let currentCamera = $0.0.isToggle ? $0.0.frontCamera : $0.0.backCamera else { return }
298+
$0.0.transitionPinchImageScale(owner: $0.0, scale: $0.1, camera: currentCamera)
299+
}).disposed(by: disposeBag)
300+
301+
reactor.pulse(\.$zoomScale)
302+
.map { $0 == 2.0 ? DesignSystemAsset.zoomout.image : DesignSystemAsset.zoomin.image }
303+
.observe(on: MainScheduler.instance)
304+
.withUnretained(self)
305+
.bind(onNext: { $0.0.zoomView.setBackgroundImage($0.1, for: .normal) })
306+
.disposed(by: disposeBag)
307+
308+
reactor.pulse(\.$pinchZoomScale)
309+
.map { $0 == 10.0 ? DesignSystemAsset.zoomout.image : DesignSystemAsset.zoomin.image }
310+
.observe(on: MainScheduler.instance)
311+
.withUnretained(self)
312+
.bind(onNext: { $0.0.zoomView.setBackgroundImage($0.1, for: .normal) })
313+
.disposed(by: disposeBag)
279314

280315
reactor.state
281316
.map { ($0.accountImage, $0.profileImageURLEntity, $0.memberId)}
@@ -322,12 +357,10 @@ public final class CameraViewController: BaseViewController<CameraViewReactor> {
322357

323358
cameraView.rx
324359
.pinchGesture
325-
.withUnretained(self)
326-
.observe(on: MainScheduler.instance)
327-
.bind(onNext: {
328-
guard let currentCamera = $0.0.isToggle ? $0.0.frontCamera : $0.0.backCamera else { return }
329-
$0.0.transitionImageScale(owner: $0.0, gesture: $0.1, camera: currentCamera)
330-
}).disposed(by: disposeBag)
360+
.map { $0.scale }
361+
.map { Reactor.Action.dragPreviewLayer($0)}
362+
.bind(to: reactor.action)
363+
.disposed(by: disposeBag)
331364

332365

333366
toggleButton
@@ -529,25 +562,22 @@ extension CameraViewController: AVCapturePhotoCaptureDelegate {
529562
self.navigationController?.popViewController(animated: true)
530563
}
531564

532-
private func transitionImageScale(owner: CameraViewController, gesture: UIPinchGestureRecognizer, camera: AVCaptureDevice) {
533-
534-
switch gesture.state {
535-
536-
case .began:
537-
owner.initialScale = camera.videoZoomFactor
538-
539-
case .changed:
540-
let minAvailableZoomScale = camera.minAvailableVideoZoomFactor
541-
let maxAvailableZoomScale = camera.maxAvailableVideoZoomFactor
542-
let availableZoomScaleRange = minAvailableZoomScale...maxAvailableZoomScale
543-
let resolvedZoomScaleRange = zoomScaleRange.clamped(to: availableZoomScaleRange)
544-
545-
let resolvedScale = max(resolvedZoomScaleRange.lowerBound, min(gesture.scale * initialScale, resolvedZoomScaleRange.upperBound))
546-
setupImageScale(owner: owner, scale: resolvedScale, camera: camera)
547-
default:
548-
return
549-
550-
}
565+
private func transitionZoomImageScale(owner: CameraViewController, scale: CGFloat, camera: AVCaptureDevice) {
566+
let minAvailableZoomScale: CGFloat = 1.0
567+
let maxAvailableZoomScale: CGFloat = 2.0
568+
let availableZoomScaleRange = minAvailableZoomScale...maxAvailableZoomScale
569+
let resolvedZoomScaleRange = zoomScaleRange.clamped(to: availableZoomScaleRange)
570+
let resolvedScale = max(resolvedZoomScaleRange.lowerBound, min(scale, resolvedZoomScaleRange.upperBound))
571+
setupImageScale(owner: owner, scale: resolvedScale, camera: camera)
572+
}
573+
574+
private func transitionPinchImageScale(owner: CameraViewController, scale: CGFloat, camera: AVCaptureDevice) {
575+
let minAvailableZoomScale: CGFloat = 1.0
576+
let maxAvailableZoomScale: CGFloat = 10.0
577+
let availableZoomScaleRange = minAvailableZoomScale...maxAvailableZoomScale
578+
let resolvedZoomScaleRange = zoomScaleRange.clamped(to: availableZoomScaleRange)
579+
let resolvedScale = max(resolvedZoomScaleRange.lowerBound, min(scale, resolvedZoomScaleRange.upperBound))
580+
setupImageScale(owner: owner, scale: resolvedScale, camera: camera)
551581
}
552582

553583
private func showPermissionAlertController() {

14th-team5-iOS/App/Sources/Presentation/Camera/Reactor/CameraViewReactor.swift

+26
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ public final class CameraViewReactor: Reactor {
2727
case didTapFlashButton
2828
case didTapToggleButton
2929
case didTapShutterButton(Data)
30+
case didTapZoomButton(CGFloat)
3031
case didTapRealEmojiPad(IndexPath)
32+
case dragPreviewLayer(CGFloat)
3133
}
3234

3335
public enum Mutation {
@@ -36,6 +38,8 @@ public final class CameraViewReactor: Reactor {
3638
case setFlashMode(Bool)
3739
case uploadImageToS3(Bool)
3840
case setAccountProfileData(Data)
41+
case setPinchZoomScale(CGFloat)
42+
case setZoomScale(CGFloat)
3943
case setProfileImageURLResponse(CameraDisplayImageResponse?)
4044
case setProfileMemberResponse(ProfileMemberResponse?)
4145
case setRealEmojiImageURLResponse(CameraRealEmojiPreSignedResponse?)
@@ -62,6 +66,8 @@ public final class CameraViewReactor: Reactor {
6266
@Pulse var realEmojiSection: [EmojiSectionModel]
6367
@Pulse var reloadRealEmojiImage: [String: URL?]
6468
@Pulse var reloadRealEmojiId: [String: String]
69+
@Pulse var zoomScale: CGFloat
70+
@Pulse var pinchZoomScale: CGFloat
6571
var updateEmojiImage: URL?
6672
var emojiType: String
6773
var selectedEmojiPadItem: String
@@ -94,6 +100,8 @@ public final class CameraViewReactor: Reactor {
94100
realEmojiSection: [.realEmoji([])],
95101
reloadRealEmojiImage: [:],
96102
reloadRealEmojiId: [:],
103+
zoomScale: 1.0,
104+
pinchZoomScale: 1.0,
97105
updateEmojiImage: nil,
98106
emojiType: "EMOJI_1",
99107
selectedEmojiPadItem: "",
@@ -116,6 +124,12 @@ public final class CameraViewReactor: Reactor {
116124
return cameraUseCase.executeToggleCameraPosition(self.currentState.isSwitchPosition).map { .setPosition($0) }
117125
case .didTapFlashButton:
118126
return cameraUseCase.executeToggleCameraFlash(self.currentState.isFlashMode).map { .setFlashMode($0) }
127+
case let .didTapZoomButton(scale):
128+
if self.currentState.zoomScale == 2.0 {
129+
return .just(.setZoomScale(self.currentState.zoomScale - scale))
130+
} else {
131+
return .just(.setZoomScale(self.currentState.zoomScale + scale))
132+
}
119133

120134
case let .didTapShutterButton(fileData):
121135
return didTapShutterButtonMutation(imageData: fileData)
@@ -127,6 +141,14 @@ public final class CameraViewReactor: Reactor {
127141
.just(.setRealEmojiPadItem(CameraRealEmojiItems.allCases[indexPath.row].rawValue)),
128142
.just(.setRealEmojiType(CameraRealEmojiItems.allCases[indexPath.row].emojiType))
129143
)
144+
case let .dragPreviewLayer(scale):
145+
let minAvailableZoomScale: CGFloat = 1.0
146+
let maxAvailableZoomScale: CGFloat = 10.0
147+
let availableZoomScaleRange = minAvailableZoomScale...maxAvailableZoomScale
148+
let zoomScaleRange: ClosedRange<CGFloat> = 1...10
149+
let resolvedZoomScaleRange = zoomScaleRange.clamped(to: availableZoomScaleRange)
150+
151+
return .just(.setPinchZoomScale(max(resolvedZoomScaleRange.lowerBound, min(scale * self.currentState.pinchZoomScale, resolvedZoomScaleRange.upperBound))))
130152
}
131153

132154
}
@@ -171,6 +193,10 @@ public final class CameraViewReactor: Reactor {
171193
newState.reloadRealEmojiImage = reloadRealEmojiImage
172194
case let .setRealEmojiId(reloadRealEmojiId):
173195
newState.reloadRealEmojiId = reloadRealEmojiId
196+
case let .setZoomScale(zoomScale):
197+
newState.zoomScale = zoomScale
198+
case let .setPinchZoomScale(pinchZoomScale):
199+
newState.pinchZoomScale = pinchZoomScale
174200
}
175201

176202
return newState

14th-team5-iOS/DesignSystem/Resources/Assets.xcassets/icons/zoom.imageset/Contents.json 14th-team5-iOS/DesignSystem/Resources/Assets.xcassets/icons/zoomin.imageset/Contents.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"images" : [
33
{
4-
"filename" : "zoom.svg",
4+
"filename" : "zoomin.svg",
55
"idiom" : "universal"
66
}
77
],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "zoomout.svg",
5+
"idiom" : "universal"
6+
}
7+
],
8+
"info" : {
9+
"author" : "xcode",
10+
"version" : 1
11+
}
12+
}

0 commit comments

Comments
 (0)