iOS์์ ํผ๋์ฒ๋ผ ์คํฌ๋กค ๊ฐ๋ฅํ ๋ฆฌ์คํธ ํ๋ฉด์ ๋ง๋ค ๋๋ ๋ณดํต UITableView๋ UICollectionView๋ฅผ ์ฌ์ฉํฉ๋๋ค.
์ด ๋ ๋ทฐ๋ ํ ๋ฒ ํ์๋ ํ๋ฉด์ ์๋์ผ๋ก ๊ฐฑ์ ํ์ง ์๊ธฐ ๋๋ฌธ์, ๋ฐ์ดํฐ๊ฐ ๋ฐ๋๋ฉด ๊ฐ๋ฐ์๊ฐ ์ง์ ๊ฐฑ์ ๋ฉ์๋๋ฅผ ํธ์ถํด์ผ ํฉ๋๋ค.
๋ํ์ ์ธ ๊ฐฑ์ ๋ฉ์๋๋ ์ด ๋ค ๊ฐ์ง์ธ๋ฐ์. ์ฐจ๋ก๋๋ก ํ๋์ฉ ์ดํด๋ด ์๋ค!
๐ reloadData()
reloadData()๋ UITableView๋ UICollectionView์์ ํ์ฌ ํ์ ์ค์ธ ๋ชจ๋ ์ ๊ณผ ์น์ ์ ์์ ํ ๋ค์ ๊ทธ๋ฆฌ๋ ๋ฉ์๋์ ๋๋ค.
๊ณต์ ๋ฌธ์๋ฅผ ์ดํด๋ณด๋ฉด…
“Call this method when the data in your data-source object changes or when you want to force the collection view to update its contents.”
— Apple Developer Documentation
์ฆ, ๋ฐ์ดํฐ ์์ค์ ๋ด์ฉ์ด ๋ฐ๋์๊ฑฐ๋, ํ๋ฉด์ ๊ฐ์ ๋ก ์๋ก๊ณ ์นจํด์ผ ํ ๋ ํธ์ถํ๋ ๋ฉ์๋์ ๋๋ค.
reloadData()์ ๋ด๋ถ ๋์
reloadData()๋ฅผ ํธ์ถํ๋ฉด ๋ค์ ์์๋ก ๋์ํ๊ฒ ๋๋๋ฐ์.
- ๊ธฐ์กด ์ ๊ณผ ์น์ ์ ์ ๋ณด๋ฅผ ๋ชจ๋ ์ ๊ฑฐํฉ๋๋ค.
- ๋ฐ์ดํฐ์์ค(UITableViewDataSource)์
- numberOfSections(in:)๊ณผ tableView(_:numberOfRowsInSection:)๋ฅผ ๋ค์ ํธ์ถํฉ๋๋ค.
- ๊ฐ ์ ์ ๋ค์ ์์ฒญํ๊ธฐ ์ํด cellForRowAt์ด ๋ชจ๋ ์ธ๋ฑ์ค์ ๋ํด ์คํ๋ฉ๋๋ค.
- ํ ์ด๋ธ๋ทฐ๊ฐ ์ ์ ์ ๊ตฌ์ฑํ๊ณ ์ ์ฒด ํ๋ฉด์ ๋ค์ ๋ ๋๋งํฉ๋๋ค.
๊ฒฐ๊ณผ์ ์ผ๋ก ํ๋ฉด์ด ์ ์ฒด ๋ฆฌ๋ก๋ ๋๋ฉฐ, ์ด์ ์
์ ์ํ๋ ์คํฌ๋กค ์์น ๋ฑ์ด ์ด๊ธฐํ๋ ์ ์์ต๋๋ค.
์ฌ์ฉ ์์
SNS์ฒ๋ผ ์ฌ๋ฌ ๊ฒ์๊ธ์ ๋ณด์ฌ์ฃผ๋ ์ปค๋ฎค๋ํฐ ํผ๋ ์ฑ์ ์๊ฐํด๋ณผ๊น์?
์๋ก์ด ๊ฒ์๊ธ์ด ์ ๋ก๋๋๋ฉด ์ ์ฒด ํผ๋๋ฅผ ๋ค์ ๋ถ๋ฌ์์ผ๊ฒ ์ฃ !
var posts = ["์์ ๊ณผ์ ์ธ์ ํ์ง ใ
ใ
", "์ค์ ๊ณต๋ถ ์์ํ์ด์!!"]
func addPost(_ newPost: String) {
posts.append(newPost)
tableView.reloadData()
}
์ด๋ reloadData()๋ฅผ ์ฌ์ฉํ๋ฉด, ํ ์ด๋ธ๋ทฐ๊ฐ ์๋ก์ด ๋ฐ์ดํฐ๋ฅผ ํฌํจํด ์ ์ฒด ํผ๋๋ฅผ ๋ค์ ํ์ํฉ๋๋ค.
์ฃผ์ํ ์
reloadData()๋ฅผ ์ฌ์ฉํ ๋๋ ๋ช ๊ฐ์ง ์ฃผ์ํ ์ ์ด ์์ต๋๋ค.
- ๋ชจ๋ ์ ์ ๋ค์ ๊ทธ๋ฆฌ๊ธฐ ๋๋ฌธ์, ๋ฐ์ดํฐ๊ฐ ๋ง์ ๊ฒฝ์ฐ ์ฑ๋ฅ ๋ถ๋ด์ด ํฝ๋๋ค.
- ์ ๋๋ฉ์ด์ ์์ด ์ฆ์ ๊ฐฑ์ ๋์ด ํ๋ฉด์ด ์๊ฐ์ ์ผ๋ก ๊น๋นก์ผ ์ ์์ต๋๋ค.
- ์ ์ ์ฝ์ ํ๊ฑฐ๋ ์ญ์ ํ๋ ์ค(beginUpdates() ๋ด๋ถ ๋ฑ)์๋ ์ฌ์ฉํ์ง ์์์ผ ํฉ๋๋ค.
- ๋ฐ์ดํฐ์์ค์ ํ ์์ ์ค์ ๋ทฐ์ ํ ์๊ฐ ์ผ์นํ์ง ์์ผ๋ฉด ํฌ๋์๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
์ฆ, reloadData()๋ ๊ฐ๋จํ๊ณ ๋น ๋ฅด์ง๋ง ๋ถ๋ถ ์ ๋ฐ์ดํธ๊ฐ ํ์ํ ์ํฉ์์๋ ๋นํจ์จ์ ์ด๊ฒ ์ฃ !
๋ฐ์ดํฐ๊ฐ ์์ฃผ ๋ฐ๋๋ ํผ๋ ํ๋ฉด์ด๋ผ๋ฉด ๋ค๋ฅธ ๊ฐฑ์ ๋ฐฉ์์ด ๋ ์ ํฉํฉ๋๋ค.
๐ prepareForReuse()
prepareForReuse()๋ UITableViewCell์ด๋ UICollectionViewCell์ด ์ฌ์ฌ์ฉ๋๊ธฐ ์ ์ ์๋์ผ๋ก ํธ์ถ๋๋ ๋ฉ์๋์ ๋๋ค.
๊ณต์ ๋ฌธ์๋ฅผ ์ดํด๋ณด๋ฉด…
“If a UITableViewCell object has a reuse identifier, the table view invokes this method just before the object is returned from dequeueReusableCell(withIdentifier:).”
— Apple Developer Documentation
์ฌ์ฌ์ฉ ํ์์ ์ ์ด ๋ค์ ๊บผ๋ด์ง๊ธฐ ์ง์ , ์ด์ ๋ฐ์ดํฐ๊ฐ ๋จ์ ์์ง ์๋๋ก ์ด๊ธฐํํ๋ ์ญํ ์ ํฉ๋๋ค.
prepareForReuse()์ ๋ด๋ถ ๋์
- ํ ์ด๋ธ๋ทฐ๊ฐ dequeueReusableCell(withIdentifier:)๋ฅผ ํธ์ถํฉ๋๋ค.
- ์ฌ์ฌ์ฉ ๊ฐ๋ฅํ ์ ์ ํ์์ ๊ฐ์ ธ์ต๋๋ค.
- ์ด ์์ ์ ์์คํ ์ด ์๋์ผ๋ก prepareForReuse()๋ฅผ ํธ์ถํฉ๋๋ค.
- ์ ๋ด๋ถ์ ์ํ(ํ ์คํธ, ์ด๋ฏธ์ง ๋ฑ)๋ฅผ ์ด๊ธฐํํ ์ ์์ต๋๋ค.
- ์ดํ cellForRowAt์ด ํธ์ถ๋์ด ์๋ก์ด ๋ฐ์ดํฐ๊ฐ ์ฃผ์ ๋ฉ๋๋ค.
์ฌ์ฉ ์์
์ปค๋ฎค๋ํฐ ํผ๋ ์ฑ์์ ์ฌ๋ฌ ๊ฒ์๊ธ์ ์คํฌ๋กคํ ๋, ์คํฌ๋กค์ด ๋น ๋ฅผ ๊ฒฝ์ฐ ์ด์ ๊ฒ์๊ธ์ด ๋จ์ ๋ณด์ผ ์ ์์ต๋๋ค.
์ด๋ prepareForReuse() ์์์ ์ ์ํ๋ฅผ ์ด๊ธฐํํ๋ฉด ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
class PostCell: UITableViewCell {
@IBOutlet weak var usernameLabel: UILabel!
@IBOutlet weak var contentLabel: UILabel!
@IBOutlet weak var thumbnailImageView: UIImageView!
override func prepareForReuse() {
super.prepareForReuse()
usernameLabel.text = nil
contentLabel.text = nil
thumbnailImageView.image = nil
}
}
์ฃผ์ํ ์
- ์ง์ ํธ์ถํ์ง ์์๋ ์์คํ ์ด ์๋์ผ๋ก ์คํํฉ๋๋ค.
- ํญ์ super.prepareForReuse()๋ฅผ ๋จผ์ ํธ์ถํด์ผ ํฉ๋๋ค.
- prepareForReuse()๋ ์ด๊ธฐํ๋ง ๋ด๋นํ๋ฉฐ, ์ค์ ๋ฐ์ดํฐ ์ธํ ์ cellForRowAt์์ ์ฒ๋ฆฌํด์ผ ํฉ๋๋ค.
- ๋น๋๊ธฐ ์ด๋ฏธ์ง ๋ก๋ฉ์ด ์๋ ๊ฒฝ์ฐ์๋ ์ด ์์ ์์ ๋ค์ด๋ก๋ ์ทจ์๋ ์ํ ์ด๊ธฐํ๋ฅผ ์ํํด์ผ ํฉ๋๋ค.
๐ reloadData() vs prepareForReuse() ๋น๊ต
| ๊ตฌ๋ถ | reloadData() | prepareForReuse() |
| ์์ | UITableView / UICollectionView | UITableViewCell / UICollectionViewCell |
| ํธ์ถ ์ฃผ์ฒด | ๊ฐ๋ฐ์๊ฐ ์ง์ ํธ์ถ | ์์คํ ์ด ์๋ ํธ์ถ |
| ํธ์ถ ์์ | ๋ฐ์ดํฐ๊ฐ ๋ฐ๋์์ ๋ (์ ๊ฒ์๊ธ ์ถ๊ฐ, ์์ ๋ฑ) | ์ ์ด ์ฌ์ฌ์ฉ๋๊ธฐ ์ง์ (์คํฌ๋กค ์ค ํ๋ฉด ๋ฐ์ผ๋ก ๋๊ฐ๋ค๊ฐ ๋ค์ ์ฐ์ผ ๋) |
| ๋ชฉ์ | ํ๋ฉด ์ ์ฒด๋ฅผ ๋ค์ ๊ทธ๋ฆผ (๋ฐ์ดํฐ ๋ฐ์) | ์ ๋ด๋ถ ์ํ ์ด๊ธฐํ (์ด์ ๋ฐ์ดํฐ ์ ๊ฑฐ) |
| ์ํฅ ๋ฒ์ | ์ ์ฒด ๋ฆฌ์คํธ (๋ชจ๋ ์ ) | ํด๋น ์ ํ ๊ฐ |
| ํธ์ถ ํ ๋์ | numberOfRowsInSection → cellForRowAt ๋ค์ ํธ์ถ๋จ | ํ ์คํธ, ์ด๋ฏธ์ง ๋ฑ ์ ์์ฑ ์ด๊ธฐํ |
| ์ฌ์ฉ ์์ | ํผ๋์ ์ ๊ธ์ด ์ถ๊ฐ๋๋ฉด ์ ์ฒด ์๋ก๊ณ ์นจ | ์คํฌ๋กค ์ ์ด์ ๊ฒ์๊ธ์ ์ด๋ฏธ์ง๊ฐ ๋จ์ง ์๋๋ก ์ด๊ธฐํ |
| ์ง์ ๊ตฌํ ํ์ ์ฌ๋ถ | ์ง์ ํธ์ถํด์ผ ํจ | ๋ฉ์๋ ์์ฒด๋ ์๋ ํธ์ถ, ๋ด๋ถ ์ด๊ธฐํ ์ฝ๋๋ ์ง์ ์์ฑํด์ผ ํจ |
๐ beginUpdates() / endUpdates()
beginUpdates()์ endUpdates()๋ ๋๋จธ์ง ์ธ ๋ฉ์๋์ ๋ฌ๋ฆฌ UITableView ์ ์ฉ ๋ฉ์๋์ ๋๋ค.
์ฌ๋ฌ ํ(row)์ด๋ ์น์ (section)์ ๋ณ๊ฒฝ ์์ ์ ํ๋์ ์ ๋๋ฉ์ด์ ์ผ๋ก ๋ฌถ์ด ์ฒ๋ฆฌํฉ๋๋ค.
beginUpdates() / endUpdates()์ ๋ด๋ถ ๋์
- beginUpdates()๋ฅผ ํธ์ถํ๋ฉด ํ ์ด๋ธ๋ทฐ๊ฐ ์ ๋ฐ์ดํธ๋ฅผ ์์ํฉ๋๋ค.
- ๊ทธ ์์์ ์ฝ์ (insertRows), ์ญ์ (deleteRows), ์ด๋(moveRow) ๋ฑ์ ๋ฉ์๋๋ฅผ ํธ์ถํฉ๋๋ค.
- endUpdates()๋ฅผ ํธ์ถํ๋ฉด ํ ์ด๋ธ๋ทฐ๊ฐ ๋ด๋ถ์ ์ผ๋ก ๋ณ๊ฒฝ ์ฌํญ์ ๊ณ์ฐํ๊ณ , ์ ์ ํ ์ ๋๋ฉ์ด์ ์ ์ ์ฉํฉ๋๋ค.
์ฌ์ฉ ์์
์ปค๋ฎค๋ํฐ ํผ๋์์ ํน์ ๊ฒ์๊ธ์ ์ญ์ ํ๊ฑฐ๋ ์ถ๊ฐํ๋ ์ํฉ์ ์๊ฐํด๋ณผ๊น์?
var posts = ["UIKit ๋๋ฌด ์ฌ๋ฐ์ด์ฉ", "์ค๋ ์ปคํผ ๋ ์์งธ โ๏ธ", "iOS 18 ์
๋ฐ์ดํธ ํ๊ธฐ"]
func updateFeed() {
posts.remove(at: 1)
posts.append("์๋ก์ด ํผ๋ ์์ฑ ์๋ฃ!")
tableView.beginUpdates()
tableView.deleteRows(at: [IndexPath(row: 1, section: 0)], with: .fade)
tableView.insertRows(at: [IndexPath(row: posts.count - 1, section: 0)], with: .automatic)
tableView.endUpdates()
}
์ด๋ฐ ์ํฉ์์ beginUpdates() / endUpdates()๋ฅผ ์ฌ์ฉํ๋ฉด ํ ๋ฒ์ ์์ฐ์ค๋ฌ์ด ์ ๋๋ฉ์ด์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ฃผ์ํ ์
- beginUpdates() ํธ์ถ ํ ๋ฐ๋์ endUpdates()๋ก ๋ซ์์ผ ํฉ๋๋ค.
- ์ญ์ ์์ ์ ์ฝ์ ๋ณด๋ค ๋จผ์ ์คํ๋์ด์ผ ์์ฐ์ค๋ฝ์ต๋๋ค.
- ๋ฐ์ดํฐ์์ค ๋ณ๊ฒฝ๊ณผ UI ์ ๋ฐ์ดํธ ์์๋ฅผ ๋ง์ถ์ง ์์ผ๋ฉด ํฌ๋์๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค.
- ๋จ์ผ ๋ณ๊ฒฝ์ด๋ผ๋ฉด insertRows ๋๋ deleteRows ๋จ๋ ํธ์ถ๋ก ์ถฉ๋ถํฉ๋๋ค.
๐ performBatchUpdates(_:completion:)
performBatchUpdates(_:completion:)๋ UITableView์ UICollectionView ๋ชจ๋์์ ์ฌ์ฉํ ์ ์๋ ์ผ๊ด ์ ๋ฐ์ดํธ ๋ฉ์๋์ ๋๋ค.
์ฝ์ , ์ญ์ , ์ด๋, ๊ฐฑ์ ์ ํ ๋ฒ์ ๋ฌถ์ด์ ์ฒ๋ฆฌํ๋ฉฐ, ์์ ์๋ฃ ์์ ์ completion ๋ธ๋ก์ผ๋ก ๋ฐ์ ์ ์์ต๋๋ค.
performBatchUpdates(_:completion:)์ ๋ด๋ถ ๋์
- ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด, ์ปฌ๋ ์ ๋ทฐ๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ฌ๋ฌ ๋ณ๊ฒฝ์ ํ๊บผ๋ฒ์ ์ฒ๋ฆฌํ ์ค๋น๋ฅผ ํฉ๋๋ค.
- ํด๋ก์ ์์ ๋ณ๊ฒฝ ์์ ์ด ๋ชจ๋ ๋ชจ์์ง๋๋ค.
- ๋ด๋ถ์ ์ผ๋ก ์ญ์ → ์ฝ์ → ์ด๋ → ๊ฐฑ์ ์์ผ๋ก ์ ๋ ฌ๋์ด ์คํ๋ฉ๋๋ค.
- ๋ชจ๋ ์ ๋๋ฉ์ด์ ์ด ๋๋๋ฉด completion ๋ธ๋ก์ด ํธ์ถ๋ฉ๋๋ค.
์ด ๋ฉ์๋๋ ํนํ UICollectionView์์ ๋ณต์กํ ๋ ์ด์์ ๋ณ๊ฒฝ์ ์์ฐ์ค๋ฝ๊ฒ ํํํ ๋ ์ ์ฉํ๊ฒ ์ฐ์ ๋๋ค.
์ฌ์ฉ ์์
ํผ๋ ํ๋ฉด์์ ํน์ ๊ฒ์๊ธ์ ์ญ์ ํ๊ณ ์๋ก์ด ๊ฒ์๊ธ์ ๋์์ ์ถ๊ฐํ๋ค๊ณ ๊ฐ์ ํด๋ด ์๋ค.
var posts = ["Swift", "Kotlin", "JavaScript"]
func updatePosts() {
posts.remove(at: 1)
posts.append("Python")
collectionView.performBatchUpdates({
collectionView.deleteItems(at: [IndexPath(item: 1, section: 0)])
collectionView.insertItems(at: [IndexPath(item: posts.count - 1, section: 0)])
}, completion: { finished in
print("์
๋ฐ์ดํธ ์๋ฃ ์ฌ๋ถ: \\(finished)")
})
}
์ด ์ฝ๋๋ฅผ ์คํํ๋ฉด ์ญ์ ์ ์ถ๊ฐ๊ฐ ํ ๋ฒ์ ์์ฐ์ค๋ฌ์ด ์ ๋๋ฉ์ด์ ์ผ๋ก ์ฒ๋ฆฌ๋ฉ๋๋ค.
๊ทธ๋ผ ์ฌ์ฉ์๋ ๋ง์น ํผ๋๊ฐ ์ค์๊ฐ์ผ๋ก ๊ฐฑ์ ๋๋ ๊ฒ์ฒ๋ผ ๋๋ผ๊ฒ ๋๊ฒ ์ฃ !
์ฃผ์ํ ์
- ์ฌ๋ฌ ๋ณ๊ฒฝ์ ํ ๋ฒ์ ๋ฌถ์ด ๋ถ๋๋ฌ์ด ์ ๋๋ฉ์ด์ ์ผ๋ก ์ฒ๋ฆฌํฉ๋๋ค.
- ์ญ์ ๋ ์ฝ์ ๋ณด๋ค ๋จผ์ ์คํ๋ฉ๋๋ค.
- ํธ์ถ ์ ์ ๋ ์ด์์์ด ์ต์ ์ํ์ธ์ง ํ์ธํด์ผ ํฉ๋๋ค.
- (์ค๋๋ ๋ ์ด์์์ด๋ฉด ๋ด๋ถ์ ์ผ๋ก reloadData()๊ฐ ๋ฐ์ํด ์ ๋๋ฉ์ด์ ์ด ๊นจ์ง ์ ์์ต๋๋ค.)
- ์์ ํ ํธ์ถ ์์๋ ๋ฐ์ดํฐ ๋ณ๊ฒฝ → ์ธ๋ฑ์ค ๊ณ์ฐ → performBatchUpdates ํธ์ถ์ ๋๋ค.
'๐ถ๐ข๐ฆ > ๐ iOS ๊ฐ๋ ํธ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [iOS / Swift] Codable & CodingKeys (0) | 2025.11.11 |
|---|---|
| [iOS / Swift] Equatable, Hashable, Comparable (0) | 2025.11.05 |
| [iOS / Swift] Enum์ด๋? (2) | 2025.11.04 |
| [iOS / Swift] Optional์ด๋? (1) | 2025.10.16 |
| [iOS / Swift] ์๋ช ์ฃผ๊ธฐ(Life Cycle)๋? (0) | 2025.10.16 |