๊ธฐ๋ณธ ์ฑ์ ๋ฉํฐ ์ ๋ ์ UI
UITableView
๋ ์ด๋ฏธ ์
๋ ์
๋ชจ๋์์ ๋ฉํฐ ์
๋ ์
์ ํ ์ ์์ต๋๋ค.
ํ์ง๋ง ์ฒดํฌ๋ฐ์ค(์ํด)๊ฐ ์ผ์ชฝํธ์ ์๊ณ ์ค๋ฅธ์ชฝ์ผ๋ก ๋ถ์ด๋ ์ต์
์ ๋ฐ๋ก ์์์ต๋๋ค.
UITableViewCell
์ editingAccessoryView
๋ผ๋ ์ธ์คํด์ค ํ๋กํผํฐ๊ฐ ์์ด์ ์จ๋ดค์ต๋๋ค๋ง, editingAccessoryType
์ ๋ฐ๋ผ ์ ํด์ง ์์ด์ฝ์ ๋ณด์ฌ์ค ๋ฟ ์ํ๋ ์ด๋ฏธ์ง๋ฅผ ๋ฃ์ ์ ์์์ต๋๋ค. ๊ทธ๋ฆฌ๊ณ ์ผ์ชฝ์ ์
๋ ์
์ฒดํฌ๋ฐ์ค๋ฅผ ์์จ ์ ์๋๊ฒ ๊ฐ๋๋ผ๊ตฌ์.. ๐๊ทธ์ง๊ฐ์ ์ ํใ
ํน์ ๋ฐฉ๋ฒ์ ์๊ณ ๊ณ์๋ค๋ฉด ๋๊ธ ๋ถํ๋๋ฆฝ๋๋ค yeye๐
๋ณ๊ฑฐ ์๋๋ฐ iOS์์ ์ ๊ณตํ๋๊ฒ ์์ด์ ๊ท์ฐฎ์์ง๋ง, ๋์์ด๋์ ๋์์ธ์ปจ์
์ ์ง์ผ๋๋ฆฌ๊ธฐ ์ํด ์ง์ ์ปค์คํ
ํ์ต๋๋ค.
(์นดํก์ ์๋ UI์ฌ์ ์ ๋ ํ ์ ์๊ฒ ๋ค ์ถ์๊ตฌ์๐)
1. ์๋ํ
๋ชจ๋์์ ๋ฉํฐ์
๋ ํ
์ผ๋ก ์ฑํ
๋ฐฉ ๋๊ฐ๊ธฐ๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
2. ์ฑํ
๋ฆฌ์คํธ/๋ด ์ฑํ
์ด๋์ ์๋ํ
์ํ๋ฅผ ์ด๊ธฐํ ํ๋ค.(์ฑํ
ํญ ๋ด๋ถ์ ํ์ด์ ธ๋ทฐ๊ฐ ์๊ณ ๊ทธ ์์ 2๊ฐ์ ํ์ด์ง๊ฐ ์์ต๋๋ค.)
๊ฐ๋ฐ ๊ณ ์์ธ ์ฌ๋ฌ๋ถ๋ค์๊ฒ๋ ์์ฃผ ์ฝ์ฃ ?
์ ๋ ์กด๋ชป์ Abstraction ์ค๋
์, HDD๋ผ ๋ ์ด์ํ์ง ๋ง์ด ํ์ต๋๋ค๐ฉ
๋จผ์ ์์์ค๋ท์ปด ์ฑ์ ์ฑํ ๋ชฉ๋ก ๋ทฐ ๋ ์ด์ด๋ฅผ ๊ฐ๋ตํ ์๊ฐํด์ผ ํ ๊ฒ ๊ฐ๋ค์
UITabBarController
- ChatMainVC(RED) - PagerView
- ChatTableVC(BLUE), MyChatTableVC(BLUE)
๋์ถฉ ์ด๋ ์ต๋๋ค.
PagerView ๋ XLPagerTabStrip ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ๊ณ ์์ต๋๋ค ใ ์๋ ์ ํ ํผ์ข ๐
์๋จ ์ฐ์ธก์ โขโขโข๋ฒํผ(๋๋ณด๊ธฐ) ๋ณด์ด์์ฃ ?
๋ค ์ ๊ฒ์ ๋๋ฅด๋ฉด ์ก์
์ํธ๊ฐ ์ฌ๋ผ์์ ํธ์ง๋ชจ๋๋ก ๋ค์ด๊ฐ ์ ์์ต๋๋ค.
ChatMainVC ๋ด๋ถ์ ๋๋ณด๊ธฐ ๋ฒํผ์ ๋๋ฅด๋ฉด, ํ์ด์ ธ๋ทฐ์ ํ์์ ์๋ ํ์ฌ ๋ทฐ์ปจํธ๋กค๋ฌ(ChatTableVC, MyChatTableVC)์ ํ
์ด๋ธ ๋ทฐ๊ฐ ๋ฉํฐ์
๋ ํ
๋ชจ๋๋ก ๋ฐ๋์ด์ผํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ํ์ฌ ๋ทฐ ์ปจํธ๋กค๋ฌ๋ฅผ ๋ฐ๊ฟ๋ ๋ง๋ค, ํธ์ง์ํ๋ ์ด๊ธฐํ ๋์ด์ผ ํฉ๋๋ท.
1. ํ
์ด๋ธ ๋ทฐ์ ๋ฉํฐ์
๋ ํ
์ปค์คํ
2. isEditing state ๊ด๋ฆฌ
ํฌ๊ฒ ๋๊ฐ์ง๋ก ๋๋ ๋ค๋ค๋ณด๊ฒ ์ต๋๋ค.
ํน์ โขโขโข๋ฒํผ ์ ๋ช ์นญ์ ์์๋์? ์ ๋
moreHorizonButton
์ด๋ผ๊ณ ๊ทธ๋ฅ ํ์ต๋๋ค;;
isEditing
UIViewController์๋ isEditing ํ๋กํผํฐ๊ฐ ์ด๋ฏธ ์์ต๋๋ค.
์ ๋ ์ด๊ฑธ๋ก ์๋ํ
๋ชจ๋ state ๋ฅผ ๊ด๋ฆฌ ํ์ต๋๋ค.
TableViewCell
ChatTableVC์ ์ด์ฉ๋๋ ChatCell์ ๋ฏธ๋ฆฌ ์ฒดํฌ๋ฐ์ค๋ค์ ๋ง๋ค์ด ๋๊ณ , isEditing ์ํ์ ๋ฐ๋ผ constraints๋ฅผ ๋ณ๊ฒฝํด ์ฃผ๊ณ , isHidden๊ฐ์ ์กฐ์ ํ์ต๋๋ค.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let chatGroupVM = vm.chatGroupVMs[indexPath.section]
let chatCellVM = chatGroupVM.chatCellVMs[indexPath.row]
let cell = chatCellVM.cellInstance(tableView, indexPath: indexPath)
guard let chatCell = cell as? ChatCellRepresentable else { return cell }
if chatGroupVM.isRemovable {
chatCell.toggleSelectionImageView(isEditing: isEditing)
chatCell.setSelected(isSelected: chatCellVM.isSelected)
} else {
chatCell.toggleSelectionImageView(isEditing: false)
chatCell.setSelected(isSelected: chatCellVM.isSelected)
}
return chatCell
}
ChatTableVC.swift
import UIKit
import SnapKit
class ChatCell: UITableViewCell, ChatCellRepresentable {
@IBOutlet weak var imgLogo: UIImageView!
@IBOutlet weak var lbTitle: UILabel!
@IBOutlet weak var lbNowChatting: UILabel!
var selectionImageView = UIImageView().then {
$0.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
$0.isHidden = true
}
private let unselectedImg = UIImage(named: "Round_Check โ 1")
private let selectedImg = UIImage(named: "Round_Check_Select โ 1")
override func awakeFromNib() {
super.awakeFromNib()
addSubview(selectionImageView)
selectionImageView.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.trailing.equalToSuperview().inset(14.0)
}
}
func toggleSelectionImageView(isEditing: Bool) {
selectionImageView.isHidden = !isEditing
lbNowChatting.snp.remakeConstraints { make in
make.width.equalTo(45.0)
make.height.equalTo(21.0)
make.centerY.equalToSuperview()
make.trailing.equalToSuperview().inset(isEditing ? 45.0 : 15.0)
}
}
func setSelected(isSelected: Bool) {
selectionImageView.image = isSelected ? selectedImg : unselectedImg
self.isSelected = isSelected
}
func setup(vm: ChatCellVMRepresentable) {
if let imageUrl = vm.chat.imageUrl, let url = URL(string: imageUrl) {
imgLogo.kf.setImage(with: url)
}
lbTitle.text = vm.title
lbNowChatting.isHidden = !vm.chat.isNowChatting
selectionImageView.image = !vm.isSelected ? selectedImg : unselectedImg
}
}
ChatCell.swift
์ ๋ฆฌํ๊ธฐ ๊ท์ฐฎ์์ ๊ทธ๋ฅ ๋ค ๊ณต๊ฐํฉ๋๋ค๐ฉ
isSelected
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let chatVM = vm.chatGroupVMs[indexPath.section].chatCellVMs[indexPath.row]
if isEditing {
chatVM.isSelected.toggle()
guard let cell = tableView.cellForRow(at: indexPath) as? ChatCellRepresentable else { return }
cell.setSelected(isSelected: chatVM.isSelected)
} else {
self.openChat(by: chatVM.chat)
tableView.reloadRows(at: [indexPath], with: UITableView.RowAnimation.none)
}
}
ChatTableVC.swift
state๋ฅผ ๋ฐ๊พธ๋ ui๋ ChatTableVC๊ฐ ์๋๋ผ ๊ทธ ์์ ๋ทฐ ์
๋๋ค.
ํ๋์ ๋ฒํผ์ผ๋ก ํ์ 2๊ฐ์ ํ
์ด๋ธ๋ทฐ์ ์ํ๋ฅผ ๊ด๋ฆฌํ๋ ๊ตฌ์กฐ๋ผ์ ์ผ๋ฐ์ ์ด์ง ์์๊ฒ ๊ฐ์์ ๐
์ฌ๊ธฐ ๊น์ง ์ฐ๋ค๊ฐ ํ์ด ๋น ์ ธ์ ๋๋จธ์ง๋ ๋ค์ ํฌ์คํ ์ ์ด์ด๊ฐ๊ฒ ์ต๋๋ค...
iOS๊ฐ๋ฐ์ ์์ํ๊ฒ ๋์์๋ ์ ํฌ ์ฑ์ MVC ํจํด์ผ๋ก ๋ง๋ค์ด์ ธ ์์๊ณ , ๊ทธ ์กฐ์ฐจ๋ ์ ํ swiftyํ์ง ์์์ต๋๋ค.
์ ๊ฐ ์กฐ๋ฅด๊ณ ์กธ๋ผ ์์คํ ๋ฆฌํฉํ ๋ง ์๊ฐ์ ์ป์ด๋ด์ด MVC -> MVVM ์ผ๋ก ๋ณ๊ฒฝํ์๋๋ฐ, ์ด๋ฒ์ ReactorKit๊น์ง ์ง์ด ๋ฃ์ด ๋ดค์ต๋๋ค.
๊ทธ๋์ ์ง๊ธ์ MVC, MVVM, ReactorKit ์ธ๊ฐ์ง๊ฐ ์์ฌ ์์๋๋ค.. ์ด์ํด ๋ณด์ด๋๋ผ๋ ์ดํดํด ์ฃผ์ธ์๐๐ป
ํฌ์คํ ํ๊ณ ์ถ์ ๋ด์ฉ์ ๊ณ์ ์์ฌ๊ฐ๋๋ฐ ๊ธ์ฐ๋๊ฒ ์ฐธ ์ฝ์ง ์๋ค์๐๐ปโโ๏ธ๐คฌ
์ผ๋จ ์๊ฐํ๊ณ ์๋๊ฒ
๋๊ฐ์ง๊ฐ ์์ต๋๋ค.
์ ํ ์ ์์๊น์?๐