์ฐ๋ฝ์ฒ ์ถ๊ฐ | ์ฐ๋ฝ์ฒ ์์ | ์ฐ๋ฝ์ฒ ์ญ์ | ์ฐ๋ฝ์ฒ ๊ฒ์ |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
Controller | ์ญํ |
---|---|
ContactsViewController | - ์ฐ์ธก ์๋จ โ ๋ฒํผ์ ๋๋ฅด๋ฉด ContactHandlerViewController ํ๋ฉด์ผ๋ก modal push๋ก ์ด๋- NavigationItem์ searchController ์ถ๊ฐ - tableView์ Cell ์ ํ ์, ์ฐ๋ฝ์ฒ๋ฅผ ์์ ํ ์ ์๋ ํ๋ฉด์ผ๋ก ์ด๋ - Cell์ Swipingํ๋ฉด ์ญ์ ์ ๋ฒํผ ํ์ฑํ ๋ฐ ์ญ์ ๊ตฌํ |
ContactHandlerViewController | - ์ฐ๋ฝ์ฒ๋ฅผ Handler ํ์
์ ์ด์ฉํ์ฌ ์ถ๊ฐ ๋ฐ ์์ ์ ๋ฐ์ - ์ถ๊ฐ : ์๋ก์ด ์ฐ๋ฝ์ฒ๊ฐ ์ถ๊ฐ - ์์ : ๊ธฐ์กด ์ฐ๋ฝ์ฒ๋ฅผ ์์ |
enum | ์ญํ |
---|---|
Handler | ContactHandlerViewController์์ add ์ edit ์ ์ํ๋ฅผ ๋ฐ์์ ์ฒ๋ฆฌํ ์ ์๋๋ก ํ์
์ ์ |
struct | ์ญํ |
---|---|
Contact | ์ฐ๋ฝ์ฒ์ ํ์ํ ์ ๋ณด(name , age ์ phoneNumber )๋ฅผ ๊ฐ๋ ๊ตฌ์กฐ์ฒด |
- ๊ธฐ์กด
ContactManager
ํ๊น์ ์ฃผ์ ํ์ผ์ContactManagerUI
์ ํ๊น ๋ฉค๋ฒ์ญ ํ์ผ๋ก ์ถ๊ฐ
- tableView ๊ตฌํ
- ContactTableViewCell๋ก tableView์์ Cell๋ก ์ฌ์ฉ
์ ์ ๋์ | ์ทจ์ ๊ธฐ๋ฅ | ์๋ฌ ๋ฐ์์ |
---|---|---|
![]() |
![]() |
![]() |
์ ํ๋ฒํธ ์
๋ ฅ์ "-"๋ฅผ ์ปค์คํ
ํค๋ณด๋๋ก ๊ตฌํํ์ง ์๊ณ ์๋์ ๊ฐ์ด ํ์ํฉ๋๋ค.
์ ํ๋ฒํธ ์ซ์์ ๊ฐ์๊ฐ
- 9๊ฐ ์ดํ์ธ ๊ฒฝ์ฐ XX-XXX-XXXX
- 10๊ฐ์ธ ๊ฒฝ์ฐ XXX-XXX-XXXX
- 11๊ฐ ์ด์์ธ ๊ฒฝ์ฐ XXX-XXXX-XXXX
class PhoneFormatter: Formatter {
override func string(for obj: Any?) -> String? {
guard let numbers = obj as? String,
Int(numbers) != nil else { return nil }
var formatType: String
var index = numbers.startIndex
var formattedNumbers = ""
switch numbers.count {
case ...9:
formatType = "XX-XXX-XXXX"
case 10:
formatType = "XXX-XXX-XXXX"
default:
formatType = "XXX-XXXX-XXXX"
}
for character in formatType where index < numbers.endIndex {
if character == "X" {
formattedNumbers.append(numbers[index])
index = numbers.index(after: index)
} else {
formattedNumbers.append(character)
}
}
while index < numbers.endIndex {
formattedNumbers.append(numbers[index])
index = numbers.index(after: index)
}
return formattedNumbers
}
}
tableView์ ๋ฐ์ํ๊ธฐ ์ํด์ reloadData()
๋ ์ ์ฒด์ ์ผ๋ก ๋ค์ ๋ถ๋ฌ์ค๋ ๊ฑฐ๋ผ์ ๋น์ฉ์ด ํฌ๋ค๋ ๊ฒ์ ์๊ณ insertRows()
๋ฅผ ์ฌ์ฉ
- ๊ฒ์ ๊ธฐ๋ฅ
- ์ญ์ ๊ธฐ๋ฅ
- ํธ์ง ๊ธฐ๋ฅ
๊ธฐ์กด ์ถ๊ฐ ๊ธฐ๋ฅ์ ํ ๋, insert๋๋ ๋ถ๋ถ์ ์ด๋ฆ์ ์ค๋ฆ์ฐจ์์ผ๋ก ์ ๋ ฌํ์ฌ ์ํ๋ฒณ์ ๋ง๊ฒ Section์ ๋ถ๋ฆฌํ์ฌ Row๋ฅผ ์ถ๊ฐ
isSearching์ด๋ผ๋ ๋ณ์๋ฅผ ๋์ด Bool๊ฐ์ ๋ฐ๋ผ tableView์ Cell์ ์ฌ๊ตฌ์ฑํ์ฌ์ ๋ณ๊ฒฝํ๋๋ก ์ฒ๋ฆฌ
- section์ ์
func numberOfSections(in tableView: UITableView) -> Int {
return isSearching ? 1 : sectionOfContacts().count
}
- section๋ง๋ค row ์
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isSearching {
return searchedContacts.count
}
...
}
- section Header ๋ณ๊ฒฝ
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if isSearching {
return "Search Results"
}
...
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
guard let selectedCell = tableView.cellForRow(at: indexPath) as? ContactTableViewCell,
let selectedContact = selectedCell.getContact(),
let selectedIndex = self.contacts.firstIndex(of: selectedContact) else {
return
}
self.contacts.remove(at: selectedIndex)
self.tableView.reloadData()
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let viewController = storyboard?.instantiateViewController(withIdentifier: "ContactHandler") as? ContactHandlerViewController {
viewController.handle = .edit
viewController.delegate = self
guard let selectedCell = tableView.cellForRow(at: indexPath) as? ContactTableViewCell,
let contact = selectedCell.getContact() else {
return
}
viewController.editContact = (contact, indexPath)
navigationController?.pushViewController(viewController, animated: true)
}
}
- tableView์
reload()
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ฝ์ ๋ฐ ์ญ์ ๋จ ํ๊ฐ์ ํ์ ์ถ๊ฐ/์ญ์ ํ๋ ๊ฒ๋ณด๋ค๋ ๋น์ฉ์ด ๋ง์ด ๋ค๊ธฐ์deleteRows()
,deleteSections()
์ ๋ํ ์ฌ์ฉ์ ๋ํด ๋ฐฐ์ ์ด์ - ์ฐ๋ฝ์ฒ๋ฅผ ์ฝ์
ํ๋ ํ๋ฉด๊ณผ ์์ ํ๋ ํ๋ฉด์ ๋์ผํ๊ฒ ๊ตฌ์ฑ์ ํ๊ธฐ์ ์ฌํ์ฉ์ ํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ๊ณ ๋ฏผ์ ํ๊ฒ ๋์๊ณ ,
ContactHandlerViewController
๋ฅผ ์ฌ์ฉํ ๋์๋ ํ์ ์ ๋ฐ์์ ๊ตฌํ์ ํ๋๋ก ๋ง๋ค์์ด์ - ๋ฐ์ดํฐ ๊ตฌ์กฐ์ table์ ์น์ ๊ทธ๋ฆฌ๊ณ ํ์ ๋ํด์ ์ด๋ป๊ฒ ํ๋ฉด ๋ ๊ตฌํ์ ํ๋ ๊ฒ ์ข์ ์ง ๊ณ ๋ฏผ์ ํ์๊ณ , ๋ฐ์ดํฐ๋ฅผ tableView์ ์น์ ์ ๋ง์ถฐ ๊ตฌ์ฑํ๋ ๊ฒ๊ณผ ๋ฐ์ดํฐ์์ tableView์์ ์น์ ๋ณ๋ก ๋ฐ์ดํฐ๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ด ๊ฒฐ๊ตญ ๊ฐ์ ๋ก์ง์ด๋ผ๊ณ ์๊ฐ๋์ด ๋ฐ์ดํฐ๋ ๋ฐฐ์ด๋ก ๊ตฌํ์ ํ๊ณ ์ข ๋ ๋์ ๋ฐฉ๋ฒ์ ๋ํด์ ๊ณ ๋ฏผ์ ํ๊ฒ ๋์์ด์.
- STEP์ BONUS๊น์ง ์งํ์ ํ๋ฉด์ tableView์์ ์ด๋ฆ๋ณ๋ก ์น์
์ ์ถ๊ฐํ์๊ณ ํ์ ์ญ์ ํ๋ ๋ฉ์๋์์ ๋ฌธ์ ๊ฐ ์๊ธด ๊ฒ์ ๋ฐ๊ฒฌํ์๊ณ ํ์ด ํ๋ ๋จ์์ ๋ Cell์ ์ง์ฐ๊ฒ ๋๋ฉด ์น์
์ ์๊ฐ ๋ง์ง ์์์ ๋ฌธ์ ๊ฐ ๋ฐ์์ ํ์์ต๋๋ค. Cell์ ์ญ์ ๋ฅผ ํ ๋ ์น์
๋ ์ญ์ ๋ฅผ ํด์ผํ๋ ๊ฒ์ ํ์ธํ๊ณ
deleteSections()
์ ์ฌ์ฉํ์์ต๋๋ค. ๋ํ, ๊ฐ๋ณ์ ์ธ ์ญ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ๊ฒ์ด ์๋๊ธฐ์beginUpdates()
,endUpdates()
๋ํ ์ฌ์ฉ์ ํ์ฌ ํด๊ฒฐํ์์ต๋๋ค. - ๋ฐ์ดํฐ๋ 1์ฐจ์ ๋ฐฐ์ด์ด๊ณ TableView์ ์น์
๊ณผ ํ์ 2์ฐจ์ ๋ฐฐ์ด ํ์์ด๋ผ์ ํ์ ๊ฐฏ์๋ฅผ ๋ง์ถ๋ ๊ณผ์ ์ด ์ด๋ ค์ ์ผ๋ฉฐ, ์น์
๋ง๋ค์ ๊ฐฏ์๋ฅผ ์ฌ์ฉํ ๋์๋
lastIndex
์firstIndex
๋ฅผ ์ด์ฉํ์ฌ ๊ฐฏ์๋ฅผ ์ธ์์ต๋๋ค