-
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
커스텀 앨범에서 이미지 편집 뷰로 이동 #44
Changes from all commits
33186d2
1a8ee8e
5ddb539
e4029e6
96f31e5
7751979
ee04e46
8b1fabb
9ad70b9
61224e7
cd70398
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import MHFoundation | ||
import Photos | ||
import Combine | ||
|
||
final class CustomAlbumViewModel { | ||
enum Input { | ||
case viewDidLoad | ||
} | ||
// MARK: - Properties | ||
@Published private(set) var photoAsset: PHFetchResult<PHAsset>? | ||
|
||
func action(_ input: CustomAlbumViewModel.Input) { | ||
switch input { | ||
case .viewDidLoad: | ||
fetchPhotoAssets() | ||
} | ||
} | ||
|
||
private func fetchPhotoAssets() { | ||
let fetchOptions = PHFetchOptions() | ||
fetchOptions.predicate = NSPredicate(format: "mediaType = %d", PHAssetMediaType.image.rawValue) | ||
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] | ||
|
||
photoAsset = PHAsset.fetchAssets(with: fetchOptions) | ||
} | ||
} | ||
Comment on lines
+19
to
+26
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. 옹 24번째 줄 옵션을 넣어서 사진만 가져오게끔 만들었습니다 ! 아무래도 해당 화면은 이미지를 넣을 목적으로 만든 앨범 화면이라 사진만 불러오게 하는 것이 적절할 것 같다고 판단해서 저렇게 만들었습니다 ! There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. 저거 Asset의 mediaType을 대충 비디오로 해주면 알아서 썸네일만 가져옵니당 .ᐟ.ᐟ |
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. 이제 안좋게 되었습니다.. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import UIKit | ||
import Photos | ||
|
||
actor LocalPhotoManager { | ||
static let shared = LocalPhotoManager() | ||
|
||
private let imageManager = PHImageManager() | ||
private let imageRequestOptions: PHImageRequestOptions = { | ||
let options = PHImageRequestOptions() | ||
options.deliveryMode = .highQualityFormat | ||
|
||
return options | ||
}() | ||
|
||
private init() { } | ||
|
||
func requestImage( | ||
with asset: PHAsset?, | ||
cellSize: CGSize = .zero, | ||
completion: @escaping @MainActor (UIImage?) -> Void | ||
) { | ||
guard let asset else { return } | ||
|
||
imageManager.requestImage( | ||
for: asset, | ||
targetSize: cellSize, | ||
contentMode: .aspectFill, | ||
options: imageRequestOptions, | ||
resultHandler: { image, _ in | ||
Task { await completion(image) } | ||
}) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,12 +2,18 @@ | |
|
||
public final class EditPhotoViewController: UIViewController { | ||
// MARK: - Properties | ||
private let photoView = UIImageView() | ||
private let clearView = UIView.dimmedView(opacity: 0) | ||
private let dimmedView1 = UIView.dimmedView(opacity: 0.5) | ||
private let dimmedView2 = UIView.dimmedView(opacity: 0.5) | ||
private let dividedLine1 = UIView.dividedLine() | ||
private let dividedLine2 = UIView.dividedLine() | ||
private let photoView: UIImageView = { | ||
let imageView = UIImageView() | ||
imageView.contentMode = .scaleAspectFit | ||
imageView.backgroundColor = .clear | ||
|
||
return imageView | ||
}() | ||
private let captionTextField: UITextField = { | ||
let textField = UITextField() | ||
textField.attributedPlaceholder = NSAttributedString( | ||
|
@@ -75,7 +81,11 @@ | |
navigationController?.navigationBar.titleTextAttributes = [ | ||
NSAttributedString.Key.font: UIFont.ownglyphBerry(size: 17), | ||
NSAttributedString.Key.foregroundColor: UIColor.white] | ||
let leftBarButton = UIBarButtonItem(title: "닫기") | ||
let closeAction = UIAction { [weak self] _ in | ||
guard let self else { return } | ||
self.navigationController?.popViewController(animated: true) | ||
} | ||
let leftBarButton = UIBarButtonItem(title: "닫기", primaryAction: closeAction) | ||
Comment on lines
+84
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 commentThe reason will be displayed to describe this comment to others. Learn more. 옹 해당 부분에 대해서 저도 이전 학습 스프린트때 학습한 적이 있는데 weak의 효과가 사라지는 경우는 Task 코드블럭 내부에서만 해당하는 것으로 알고있습니다 ! 위 클로저는 UIAction으로 Task 블럭이 아니기 때문에 self를 언래핑해도 weak 참조가 가능한 것으로 알고있습니다. 추가로 위 코드는 비동기 작업을 해당 클로저 내부에서 하고있지 않기 때문에 괜찮지 않을까요?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 제 생각에는 윤철님 말씀이 맞는 것같습니다. 다만, weak self 목적이 강한순환참조를 방지하려는 목적이기 때문에, 저렇게 사용하는 것자체는 동의합니다. Task나 저 Action이나 모두 escaping closure이기 때문에 weak self로 캡쳐한 후 |
||
leftBarButton.setTitleTextAttributes( | ||
[NSAttributedString.Key.font: UIFont.ownglyphBerry(size: 17), | ||
NSAttributedString.Key.foregroundColor: UIColor.white], | ||
|
@@ -158,20 +168,24 @@ | |
|
||
private func configureButtonAction() { | ||
let cropButtonAction = UIAction { _ in | ||
// TODO: - Crop Action | ||
Check warning on line 171 in MemorialHouse/MHPresentation/MHPresentation/Source/EditPhoto/EditPhotoViewController.swift GitHub Actions / SwiftLint
|
||
} | ||
let rotateButtonAction = UIAction { _ in | ||
// TODO: - Rotate Action | ||
Check warning on line 174 in MemorialHouse/MHPresentation/MHPresentation/Source/EditPhoto/EditPhotoViewController.swift GitHub Actions / SwiftLint
|
||
} | ||
let drawButtonAction = UIAction { _ in | ||
// TODO: - Draw Action | ||
Check warning on line 177 in MemorialHouse/MHPresentation/MHPresentation/Source/EditPhoto/EditPhotoViewController.swift GitHub Actions / SwiftLint
|
||
} | ||
cropButton.addAction(cropButtonAction, for: .touchUpInside) | ||
rotateButton.addAction(rotateButtonAction, for: .touchUpInside) | ||
drawButton.addAction(drawButtonAction, for: .touchUpInside) | ||
} | ||
|
||
func setPhoto(image: UIImage?) { | ||
photoView.image = image | ||
} | ||
} | ||
|
||
extension EditPhotoViewController: UITextFieldDelegate { | ||
// TODO: - TextField의 텍스트 처리 | ||
Check warning on line 190 in MemorialHouse/MHPresentation/MHPresentation/Source/EditPhoto/EditPhotoViewController.swift GitHub Actions / SwiftLint
|
||
} |
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.
P3. 뷰모델의 속성에 직접 접근하는 것 대신 함수를 만들어주면 어떨까요?
func photo(at indexPath: indexPath) -> 사진 느낌?
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.
해당 부분도 고민을 많이 한 지점이었는데 cell의 delegate나 dataSource 관련된 함수 내부에서 ViewModel과 어떻게 바인딩을 해야할지를 모르겠어서 저렇게 직접 접근하는 방식을 사용했던 것 같습니다..
데이터의 단방향 flow를 만들고 싶어서 ViewModelInput이라는 열거형을 만들고 Input와 output을 나눠 관리하려했는데 메서드를 넣으면 훔... 그래도 확실히 뷰모델의 속성에 직접 접근하는게 어색해보일 수 있을 것 같네요.. 일단 조금 더 고민해보겠습니다 .ᐟ.ᐟ