๊ณต๋ถํ ๋ด์ฉ์ ์ ๋ฆฌํ ๊ธ์ ๋๋ค.
๋ฌธ์
์ฌ์ง ์ ํ ์ ๋ฒํธ ํ๊ธฐ(๋๋ฒ๋ง) ๊ตฌํํ๊ธฐ. ํน์ ์ฌ์ง ์ ํ ํด์ ์ ๋ณ๊ฒฝ์ฌํญ์ด ์ ์ฒด ๋ฒํธ ํ๊ธฐ์ ๋ฐ์๋์ด์ผ ํ๋ค.
1. cell ๋ด ๋ฒํผ ์ ํ ์ด๋ฒคํธ
2. ํน์ ์ฌ์ง ์ ํ ๋ชฉ๋ก์ ์ถ๊ฐํ๊ธฐ
3. ํน์ ์ฌ์ง ์ ํ ํด์ ํ๊ธฐ
4. ์์ ์ ๊ตฌํํ๋ฉด์ ๊ฒฝํํ๋ ์ค๋ฅ
5. ๊ฐ์ ํ ๋งํ ๋ถ๋ถ
1. cell ๋ด ๋ฒํผ ์ ํ ์ด๋ฒคํธ
2. ํน์ ์ฌ์ง ์ ํ ๋ชฉ๋ก์ ์ถ๊ฐํ๊ธฐ
ํด๋์ค์ ์ ์ฒด ์ฌ์ง์ด ๋ ๋ฐฐ์ด๊ณผ ์ ํ๋ ์ฌ์ง์ด ๋ด๊ธธ ๋ฐฐ์ด์ ์ ์ธํ๋ค.
//ImagePickerViewController.swift
class ImagePickerViewController: UIViewController {
...
var selectedImages: [UIImage] = []
var images: [ImageData] = []
...
}
์ฌ๊ธฐ์ images ๋ฐฐ์ด์ ํ์ ์ ๊ตฌ์กฐ์ฒด๋ฅผ ์ฌ์ฉํด ๋ง๋ ImageData๋ฅผ ์ฌ์ฉํ๋ค. ์ฌ์ง์ด ์ ํ๋ ๊ฒฝ์ฐ, ๋ช ๋ฒ์งธ๋ก ์ ํ๋์๋์ง ์ ์ฅํ๊ธฐ ์ํด selectedNumber ๋ณ์๋ฅผ ์ ์ธํ๋ค. ๋ฒํธ๋ฅผ ์ ์ฅํ๋ ๋ณ์์ด๋ฏ๋ก Intํ์ด์ง๋ง ์ ํ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๊ธฐ ์ ์๋ ๊ฐ์ด ์์ผ๋ฏ๋ก ์ต์ ๋๋ก ์ ์ธํ๋ค.
//ImageData.swift
struct ImageData {
let image: UIImage
var selectedNumber: Int?
}
์ฌ์ง ๋ด ๋ฒํผ ํด๋ฆญ ์ ํธ์ถ๋๋ ๋ฉ์๋์์ ํน์ ์ฌ์ง ์ ํ ๋ชฉ๋ก์ ์ถ๊ฐํ๊ธฐ ์์ ์ ๊ตฌํํ์.
UICollectionViewControllerDataSource์ collectionView(_:cellForItemAt:) ๋ฉ์๋๋ฅผ ํตํด cell์ ๊ตฌ์ฑํ ๋, ImageCollectionViewCell์ index ํ๋กํผํฐ์ cell์ row ์์๋ฅผ ์ ์ฅํ์ฌ ํด๋น ์ฌ์ง์ด images ๋ฐฐ์ด์ ๋ช ๋ฒ์งธ์ ์์นํ๋์ง ํ์ธํ์. ๋ง์ฝ ์ ํ๋ ์ ์ด ์๋ค๋ฉด, ํด๋น ์ฌ์ง์ selectedImages ๋ฐฐ์ด์ ์ถ๊ฐํ๊ณ selectedNumber์ ๋ช ๋ฒ์งธ๋ก ์ถ๊ฐ๋์๋์ง ๋ฒํธ๋ฅผ ์ ์ฅํ๋ค.
//ImagePickerViewController.swift
extension ImagePickerViewController: ImageCollectionViewCellDelegate {
func didSelectCountButton(_ cell: ImageCollectionViewCell) {
if images[cell.index].selectedNumber != nil {
} else {
let image = images[cell.index].image
selectedImages.append(image)
images[cell.index].selectedNumber = selectedImages.count //0๋ฒ์งธ๋ถํฐ ํ ๋นํด๋ ๋๋ค
}
imageCollectionView.reloadData()
}
}
3. ํน์ ์ฌ์ง ์ ํ ํด์ ํ๊ธฐ
ํน์ ์ฌ์ง์ ๋ฐฐ์ด์์ ์ ๊ฑฐํ๋ ์์ ์ ๊ฐ๋จํ๋ค. ํ์ง๋ง ์ฐ๋ฆฌ๋ ์ ํ์ด ํด์ ๋์์ ์ ์ด๋ฌํ ๋ณํ๊ฐ ๋ฒํธ ํ๊ธฐ์ ๋ฐ์๋์ด์ผ ํ๋ค.
์) ๊ฐ1-๋2-๋ค3-๋ผ4 => ๋ค3 ์ ๊ฑฐ => ๊ฐ1-๋2-๋ผ3
ํด๋น ์ฌ์ง์ด ์ ํ๋ ์ ์ด ์๋ค๋ฉด selectedImages ๋ฐฐ์ด์์ ํด๋น ์ฌ์ง์ด ์ ๊ฑฐ๋๋ค. ๊ทผ๋ฐ ๋ง์ฝ ๋ง์ง๋ง ์ฌ์ง์ด ์๋ ์ค๊ฐ ์์์ ์ฌ์ง์ด ์ญ์ ๋๋ค๋ฉด ์ ํ ํด์ ๋ ์ฌ์ง์ ๋ฒํธ ์ด์์ ๋ฒํธ๋ถํฐ ํ๊ธฐ ์์ ์ด ํ์ํ๋ค. A์ if๋ฌธ์ ๊ทธ๋ฌํ ์กฐ๊ฑด์ ํด๋นํ ๊ฒฝ์ฐ ๊ทธ๋ฌํ ์์ ์ ์ํํ๋ ๋จ๋ฝ์ด๋ค.
extension ImagePickerViewController: ImageCollectionViewCellDelegate {
func didSelectCountButton(_ cell: ImageCollectionViewCell) {
if images[cell.index].selectedNumber != nil {
guard let selectedNumber = images[cell.index].selectedNumber else {return}
selectedImages.remove(at: selectedNumber - 1)
if selectedNumber <= selectedImages.count { //A
images = images.map{
guard var number = $0.selectedNumber else {return ImageData(image: $0.image, selectedNumber: nil)}
if number > selectedNumber {
number -= 1
}
return ImageData(image: $0.image, selectedNumber: number)
}
}
images[cell.index].selectedNumber = nil
} else {
...
}
imageCollectionView.reloadData()
}
}
4. ์์ ์ ๊ตฌํํ๋ฉด์ ๊ฒฝํํ๋ ์ค๋ฅ
์ ์ฒด ์ฌ์ง์ด ๋ด๊ธด images ๋ฐฐ์ด๊ณผ ์ ํ๋ ์ฌ์ง์ด ๋ด๊ธด selectesImages ๋ฐฐ์ด์ ๊ฐ์ง๊ณ ์ฌ์ง ์ ํ ์ ๋ฒํธ ํ๊ธฐ(๋๋ฒ๋ง) ๊ตฌํํ๊ธฐ ์ , ๊ฐ cell์ ImageCollectionViewCell.swift์ ์ ํ๋ ์์๋ฅผ selectedIndex์ ๋ด์ ๊ตฌํ์ ์๋ํ์๋ค.
์ฒ์์ ์ ์๋ํ๋ค ํ๋จ๋์์ง๋ง, ์คํฌ๋กค์ ์์ง์ฌ ๋ณด๋ ์ ํํ์ง ์์ ์ฌ์ง์ด ์ ํ๋์๋ค๊ณ ํ์๋๊ฑฐ๋ ์ซ์๊ฐ ์์ด๋ ๋ฑ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค. ์ด๋ฌํ ์ค๋ฅ๊ฐ ๋ฐ์ํ ์ด์ ๋ ๋ด ์๊ฐ์ cell ์์ฑ ์ collectionView์ dequeueReusableCell(withReuseIdentifier:for:) ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ ๊ทธ๋ฐ ๊ฒ ๊ฐ๋ค.
dequeueReusableCell(withReuseIdentifier:for:)
identifier์์ ์ฐพ์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ cell ๊ฐ์ฒด๋ฅผ ํ์์ ๋บ๋ค.
dequeueReusableCell(withReuseIdentifier:for:)๋ collectionView์์ ์ cell์ ์์ฒญํ ๋ DataSource๋ก๋ถํฐ ํธ์ถ๋๋ค. ์๋ฅผ ๋ค์ด ์คํฌ๋กค์ ์ด๋์์ผ ๋ค๋ฅธ ๋ฐ์ดํฐ๋ฅผ ํ์ธํ ๋๊ฐ ์๋ค. ์ด ๋ฉ์๋๋ ์ cell์ ์์ฒญ๋ฐ์ผ๋ฉด ์๋กญ๊ฒ cell์ ์์ฑํ๊ฑฐ๋, ์กด์ฌํ๋ cell ์ค ์ฌ์ฉ ๊ฐ๋ฅํ ๊ฒ์ collectionView์๊ฒ ์ ๋ฌํ๋ค. ์ฌ๊ธฐ์ ๊ธฐ์กด cell์ ์ ๋ฌํ ๊ฒฝ์ฐ cell์ prepareForReuse() ๋ฉ์๋๋ฅผ ํธ์ถํ๋๋ฐ, ๋ฐ๋ก ์ด ๋ฉ์๋์ ์ํด ์์ ๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒ ๊ฐ๋ค.
prepareForReuse()
๋ทฐ๋ฅผ ๋ค์ ์ฌ์ฉํ ์ ์๋๋ก ์ค๋นํ๊ธฐ ์ํด ํ์ํ ๋ชจ๋ ์ ๋ฆฌ๋ฅผ ์ํํ๋ค. (any clean up necessary)
์ ๋ฉ์๋๋ cell์ ์ฌ์ฌ์ฉํ๊ธฐ ์ํด ๊ธฐ์กด์ cell์ ์ ๋ฆฌํ๋ค. ์ฆ, ์ ํ๋ ์ฌ์ง cell์ด ์คํฌ๋กค์ด ๋๋ฉด์ ์ ๋ฆฌ๋ผ ์ฌ์ฌ์ฉ๋์ด์ ์คํฌ๋กค์ ํ๋ฉด ์ ํ๋ ์ฌ์ง์ cell์ด ๋ค๋ฅธ ์ฌ์ง์ cell์ด ๋์ด๋ฒ๋ฆฐ ๊ฒ์ด๋ค.
๋ฐ๋ผ์ ์ฌ์ง์ ๊ฐ๊ฐ์ ์ํ๋ฅผ ๊ตฌ๋ถํ๊ธฐ ์ํด์๋ ๋ฐ๋ก ๋ฐ์ดํฐ ๋ฆฌ์คํธ๋ฅผ ๋ง๋ค์ด ์ ์ฅํด์ผ ํ๋ค.
์ง๊ธ๊น์ง ๊ณต๋ถํ๊ณ ์ ๋ฆฌํ ๋ฐ๋ก๋ ์์ ๊ฐ์ ์ด์ ๋ก ํด๋น ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒ ๊ฐ์๋ฐ, ๊ทธ๋ ๋ค๋ฉด index ํ๋กํผํฐ๋ ์ ์ํฅ์ด ์์๊น? ์์ง ๋ ๊ณต๋ถํด๋ด์ผ ํ ๊ฒ ๊ฐ๋ค.
5. ๊ฐ์ ํ ๋งํ ๋ถ๋ถ
ํ์ฌ ์์ ์ Swift์์ ์ ๊ณตํ๋ Collectionํ์ ์ธ ๋ฐฐ์ด์ ์ฌ์ฉํด ๊ตฌํํ๋ค. ํ์ง๋ง ๋ฐฐ์ด์์ insert, remove ๋ฑ๊ณผ ๊ฐ์ ์์ ์ O(n) ์๊ฐ์ด ์์๋๋ค. ๋ฐ๋ผ์ ๋ฐ์ดํฐ๊ฐ ๋ง์์ง ๊ฒฝ์ฐ ๋ฐฐ์ด์ ์ฌ์ฉ์ ๋นํจ์จ์ ์ด๋ค.
์ด๋ฌํ ๋จ์ ์ LinkedList ๋๋ ๋ค๋ฅธ ์๋ฃ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ๋ฉด ํด๊ฒฐํ ์ ์์ ๊ฒ ๊ฐ๋ค. ์ถํ ์์ ์ ํตํด ๊ฐ์ ํด๋ณด๋๋ก ํ์.
๊ทธ๋ฆฌ๊ณ ์ ํ ๋๋ ์ ํ ํด์ ์ CollectionView.reload()๋ฅผ ์ฌ์ฉํด collectionView๋ฅผ ๊ฐฑ์ ํ๋๋ฐ, ์ถ๊ฐ ๋๋ ์ ๊ฑฐ ์ ์ฌ์ฉ๋๋ collectionView์ ๋ฉ์๋๊ฐ ์์ผ๋ฏ๋ก ๊ณต๋ถํด ์์ ํ์.