✔︎ 오늘의 정리
- PopUpButton의 menu 선택하기
- PHPicker에서 추가된 사진이 계속 추가될 때
- CustomSegmentedControl
PopUpButton의 menu 선택하기
if let menu = weightUnitButton.menu?.children {
menu.forEach { action in
print(action)
if action.title == pet.weightUnit.rawValue {
let element = action as? UIAction
element?.state = .on
}
}
}
찢었다...
ㅜㅜ
다운캐스팅이 맞는 거 같은데 순간 생각나서 이.. 이거되나???? 하고 해봤더니 진짜됨...
ㅁㅊ다......
아무튼 뭘 해냈냐면 기존에 popUpButton으로 kg / g / lb 같은 단위를 선택할 수 있도록 했다. 저장할 때도 단위에 따라서 다르게 저장했는데 아니~~ 생각해 보니까 그럼 수정할 때도 팝업 버튼에 그거랑 같은 단위가 자동으로 떠야 사용자가 편할 거아닝가?
내가 내 무덤을 판 느낌이었지만 포기할 수 없었다 ,,
누가 먼저 만든 거 없나 찾아보다가 없길래 그냥 쓰자!!!!! 하고 써봤다...
삽질을 좀 하긴 했지만 뿌듯허다
menu?.children으로 불러온 친구는 UIMenuElement라서 .state가 없다...
ㅇ_ㅇ
그래서 이 친구를 UIAction으로 바꿔줘야 내가 원하는 선택된 상태로 뜨게 된다.
생각해 보면 UIMenuElement에는 UIAction을 뭐 안 바꾸고 그냥 넣었지 않은가??
그럼 UIMenuElement가 더 넓은 개념이라 UIAction 말고도 다른 넘들을 포괄하여 받아들일 수 있을 것이다
글서 다운캐스팅을 했더니... 짜잔~~~~~~
하 ㅋㅋ 다운캐스팅......... 배우고 알기만 알았지 이럴 때 사용하는거구나.ᐟ.ᐟ.ᐟ.ᐟ.ᐟ.ᐟ.ᐟ.ᐟ.ᐟ.ᐟ.ᐟ.ᐟ 싶다 ㅁㅊ다 ...
오늘 진짜 삽질만 해서 블로그 올릴 게 없지 않나 싶었는데 와 이건 블로그 올령야지 대박 ㅋㅋ 하고 바로 썼다...
잘 쓴 코드는 아닌 것 같지만..... 그래두~~~~~~
.. ...
대박이당...........................................
PHPicker에서 동일한 사진이 계속 추가될 때
글로 하니 되게 엥? 무슨 소리지? 싶은데... 명확히 상황을 보자면 위 gif와 같다.
그러니까, PHPicker에서 먼저 사진을 추가하고 난 이후에 다시 사진을 추가하려고 할 때, 이전의 사진들이 기본으로 선택되어 있다. 이거까지는 아주 좋은데 문제가 있다면 미리 추가되어 있던 사진들이 같이 새로운 사진과 함께 올라간다는 게 문제였다.
그래서 기존에 images.append만 있던 코드에서 로직을 좀 짜주었다.
extension DiaryViewController: PHPickerViewControllerDelegate, AddDelegate {
func openPhotoAlbum(_ sender: PHPickerViewController) {
// picker 기본 설정!!
self.present(sender, animated: true, completion: nil)
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
// 이미지 클릭 시 화면 dismiss
picker.dismiss(animated: true)
for result in results {
if result.itemProvider.canLoadObject(ofClass: UIImage.self) {
let type: NSItemProviderReading.Type = UIImage.self
result.itemProvider.loadObject(ofClass: type) { (image, error) in
if let image = image as? UIImage {
DispatchQueue.main.async {
print(self.images.count)
if !(self.images.contains(image)) {
print(self.images)
// image가 저장되는 게 달라서 ㅠㅠ 같은 이미지여도 각각 같은 이미지로 인식댐
self.images.append(image)
}
}
} else {
// 다시 시도 Alert
print(error?.localizedDescription)
self.sendOneSidedAlert(title: "이미지를 저장할 수 없습니다.", message: "한 번 더 시도해 주세요!")
}
}
}
}
}
}
해당 코드는 이러하다.
하지만~~~!!! ㅠ_ㅠ 주석에서도 알 수 있듯이 데이터를 가지고 오게 된다면 같은 이미지라도 컴퓨터는 다르게 인식하여 암 생각 없이 추가하게 된다.
그 어떤 로직을 짜도 돌아가지 않고 추가만 되길래 뭐지??? 했다
다른 곳들은 대체 어떻게 구현하는 거냐... ... 하고 봤더니 당근마켓은 그냥 추가한 것을 또 추가할 수 있도록 했드라. (껐다가 다시 켰을 때)
사실 UIImagePicker를 이용하면 그렇게 그냥 간단하게 구현할 수도 있을 것 같은데 좀 열받기도 하고 관련하여 방법을 찾아서 정리해 봤다 ㅋㅋ
근데 결국에는 이걸루 안 씀......
카메라를 사용하는 UIImagePicker는 identifier가 없어서 둘이 동시 적용이 안 되더라
아무튼... 삽질 과정이라도 적어놓으려구 한다 ㅋㅋ
https://ios-daniel-yang.tistory.com/83
[Swift/TIL #9] PHPickerViewController에 대하여
[TIL #9] 2023 / 04 / 03 ~ 2023 / 04 / 06 사진을 가져오려 하는데 iOS 14 이상부터는 UIImagePickerController 대신 PHPickerViewController를 사용하라고 하더라고요. 그래서 오늘은 PHPickerViewController에 대해서 알아보겠
ios-daniel-yang.tistory.com
참고한 블로그는 요기
원하는 결과는 나왔다!
다만 문제가 있다면 카메라로 찍었을 때 image들이 초기화된다는 점과 카메라 이미지와 사진 보관함 이미지가 중첩이 안 된다는 것, ,, ^^
더 찾아보면 할 수 있겠지만 일단 구현이 바쁘기에~~~~!!! ㅠㅠ
다른 곳도 보면 다들 이전에 선택했던 이미지를 보여주기보다는 그냥 새로운 이미지를 추가하는 식으로 구현했더라
나도 그렇게 해야댈 거 같다...
아무튼~!
위에 전역변수로
private var selections = [String : PHPickerResult]()
private var selectedAssetIdentifiers = [String]()
식별자들을 담을 배열을 하나 생성해 준다.
extension DiaryViewController: PHPickerViewControllerDelegate, AddDelegate {
func openPhotoAlbum(_ sender: PHPickerViewController) {
var config = PHPickerConfiguration(photoLibrary: .shared())
config.filter = .images
config.selectionLimit = 5
config.selection = .ordered
config.preferredAssetRepresentationMode = .current
// 이 친구를 통해서 선택된 이미지의 identifier를 비교함
config.preselectedAssetIdentifiers = selectedAssetIdentifiers
let imagePicker = PHPickerViewController(configuration: config)
imagePicker.delegate = self
self.present(imagePicker, animated: true)
}
private func displayImage() {
// 순서대로 안 들어가길래 dispatchGroup을 이용해서 넣어줬다 ,, ^_^
let dispatchGroup = DispatchGroup()
var imagesDict = [String: UIImage]()
for (identifier, result) in selections {
dispatchGroup.enter()
let itemProvider = result.itemProvider
if itemProvider.canLoadObject(ofClass: UIImage.self) {
itemProvider.loadObject(ofClass: UIImage.self) { image, error in
guard let image = image as? UIImage else { return }
imagesDict[identifier] = image
dispatchGroup.leave()
}
}
}
dispatchGroup.notify(queue: DispatchQueue.main) { [weak self] in
guard let self = self else { return }
self.images.removeAll()
for identifier in self.selectedAssetIdentifiers {
guard let image = imagesDict[identifier] else { return }
self.images.append(image)
}
}
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
var newSelections = [String: PHPickerResult]()
for result in results {
let identifier = result.assetIdentifier!
newSelections[identifier] = selections[identifier] ?? result
}
selections = newSelections
selectedAssetIdentifiers = results.compactMap { $0.assetIdentifier }
if !selections.isEmpty {
displayImage()
} else {
self.images = []
}
}
^_^ ......
이후 수정한 코드는 아래와 같다......
// 5개까지 사진을 등록할 수 있도록 제한하기 위해서 picCount 변수를 맹글어 주었다.
var picCount: Int = 0
// 선택한 이미지를 모으는 친구 ,, ^_^
private var images: [UIImage] = [] {
didSet {
collectionView.reloadData()
}
}
extension DiaryViewController: PHPickerViewControllerDelegate, AddDelegate {
func openPhotoAlbum(_ sender: PHPickerViewController) {
if 5 - picCount < 1 {
// 선택한 사진이 5개가 되면 추가하는 셀이 사라지도록 구성해 놨지만
// 혹시 모르니까!! 일단 Alert을 추가해 놓았다 ,, :3
self.sendOneSidedAlert(title: "사진은 5장까지 추가할 수 있습니다!")
}
var config = PHPickerConfiguration(photoLibrary: .shared())
config.filter = .images
// 이럼 매번 창이 띄워질 때 사진 limit 안에서 사진을 선택할 수 있당
config.selectionLimit = 5 - picCount
config.selection = .ordered
let imagePicker = PHPickerViewController(configuration: config)
imagePicker.delegate = self
self.present(imagePicker, animated: true)
}
func picker(_ picker: PHPickerViewController, didFinishPicking results: [PHPickerResult]) {
picker.dismiss(animated: true)
// 이전 코드에서 사용했던 disPatchGroup은 가지고 왔다 ,, ^_^
// 사유: 이 친구가 비동기로 동작하기 때문에 비교적 크기가 작은 순서대로 착착 쌓이게 돼서~~!!
let dispatchGroup = DispatchGroup()
var images = [UIImage]()
for result in results {
dispatchGroup.enter()
let itemProvider = result.itemProvider
if itemProvider.canLoadObject(ofClass: UIImage.self) {
let type: NSItemProviderReading.Type = UIImage.self
itemProvider.loadObject(ofClass: type) { [weak self](image, error) in
guard let self = self else { return }
if let image = image as? UIImage {
images.append(image)
dispatchGroup.leave()
} else {
// 다시 시도 Alert
print(error?.localizedDescription)
self.sendOneSidedAlert(title: "이미지를 저장할 수 없습니다!", message: "한 번 더 시도해 주세요!")
}
}
}
}
dispatchGroup.notify(queue: DispatchQueue.main) { [weak self] in
guard let self = self else { return }
if self.images.count + images.count > 5 {
// 요기도 혹시 몰라서 Alert 추가
self.sendOneSidedAlert(title: "사진은 5장까지 추가할 수 있어요!")
return
} else {
// 하 ... 첨부터 이렇게 할 걸 그랬다
// 추가 가능할 경우에는 picCount에 이미지 갯수를 추가해 주고 넘겨줌
picCount += images.count
self.images.append(contentsOf: images)
}
}
}
}
extension DiaryViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func takePhoto(_ sender: UIImagePickerController) {
present(sender, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
self.images.append(image)
picCount += 1
}
picker.dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
picker.dismiss(animated: true, completion: nil)
}
func selectFile() {
}
}
extension DiaryViewController: DeleteDelegate {
func deleteImages(image: UIImage) {
if let firstIndex = self.images.firstIndex(of: image) {
self.images.remove(at: firstIndex)
self.picCount -= 1
}
}
}
PHPicker를 띄울 때 갯수 제한을 자체로 해주기 위해서 picCount라는 변수를 썼는데 이것 말고도 좀,,, 더 괜찮게 하는 방법이 있지 않을까???? 싶다......
근데 지금 너무 바뻐서 그냥 하려고 한다
왜 갑자기 이 노래가 생각낫지?
아무튼...........
원래 시도했던 방법은 선택된 이미지에서 더 추가되어도 이전에 선택했던 이미지가 또 추가되지 않는 방법이었는데
지금은 그냥 새 picker를 띄워서 선택된 이미지가 picker에서 보이지 않도록 맹글어 버렸다 ,, ^_^6
삭제나 카메라 적용까지 생각한다면 이 방법이 진짜훨나은거같다
https://ios-daniel-yang.tistory.com/83
[Swift/TIL #9] PHPickerViewController에 대하여
[TIL #9] 2023 / 04 / 03 ~ 2023 / 04 / 06 사진을 가져오려 하는데 iOS 14 이상부터는 UIImagePickerController 대신 PHPickerViewController를 사용하라고 하더라고요. 그래서 오늘은 PHPickerViewController에 대해서 알아보겠
ios-daniel-yang.tistory.com
https://developer.apple.com/videos/play/wwdc2021/10046/
Improve access to Photos in your app - WWDC21 - Videos - Apple Developer
PHPicker is the simplest and most secure way to integrate the Photos library into your app — and it's getting even better. Learn how to...
developer.apple.com
참고한 블로그와 WWDC 문서는 이쪽!!
CustomSegmentedControl
https://ios-development.tistory.com/963
[iOS - swift] 2. UISegmentedControl - 커스텀 방법, PageViewController와 사용 방법
1. UISegmentedControl - 기본 사용 방법 2. UISegmentedControl - 커스텀 방법, PageViewController와 사용 방법 UISegmentedControl 커스텀 방법 클래스 준비 import UIKit final class UnderlineSegmentedControl: UISegmentedControl { } UISeg
ios-development.tistory.com
How to display only bottom border for selected item in UISegmentedControl?
I'm extremely new to iOS development and ran into some trouble while building an app for a course. I created a segmented control and its init function (shown below) is being called in the view
stackoverflow.com
아오 맨날 다른 오류 있음 이거까지... 해서 올려야즤 ㅋ 하다가 미뤄진ㄷ ㅏ,,
8일부터 미뤘기 땜에 오늘이라도 올리려구 한다.
나 출시할수잇겟지......
젭알
'TIL' 카테고리의 다른 글
[SeSAC] October 19, 2023 (3) | 2023.10.19 |
---|---|
[SeSAC] October 15, 2023 (2) | 2023.10.16 |
[SeSAC] October 7, 2023 (0) | 2023.10.07 |
[SeSAC] October 3, 2023 (3) | 2023.10.04 |
[SeSAC] September 17, 2023 (0) | 2023.09.20 |