์ข์ ์ฝ๋ ๊ตฌ์ฑ์ ์๋ ์ ์์ง๋ง, ๊ฐ๋จํ ๋ฐฉ๋ฒ์ผ๋ก AutomaticDimension์ ํ์ฉํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ์ด๋ณด๋ ค๊ณ ํฉ๋๋ค!
๊ธฐ๋ณธ ์
ํ
์ฝ๋๋ ์๋ ์ ์ ๊ธ๋ก ์ ์ด๋๊ฒ ์ต๋๋ค :)
<VC>
import UIKit
import SnapKit
class ViewController: UIViewController {
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
configureTableView()
}
func configureTableView() {
view.addSubview(tableView)
tableView.snp.makeConstraints {
$0.edges.equalTo(view.safeAreaLayoutGuide)
}
tableView.delegate = self
tableView.dataSource = self
tableView.register(TestTableViewCell.self, forCellReuseIdentifier: TestTableViewCell.id)
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: TestTableViewCell.id, for: indexPath) as? TestTableViewCell else { return UITableViewCell() }
cell.tableVew = tableView
return cell
}
}
<Cell>
import UIKit
class TestTableViewCell: UITableViewCell {
let descriptionLabel = UILabel()
let dropDownButton = UIButton()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
configureUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configureUI() {
contentView.addSubview(descriptionLabel)
contentView.addSubview(dropDownButton)
let safeArea = contentView.safeAreaLayoutGuide
descriptionLabel.snp.makeConstraints {
$0.top.equalTo(safeArea).offset(20)
$0.horizontalEdges.equalTo(safeArea).inset(20)
$0.bottom.equalTo(dropDownButton.snp.top).offset(-10)
}
dropDownButton.snp.makeConstraints {
$0.top.equalTo(descriptionLabel.snp.bottom)
$0.centerX.equalTo(safeArea)
$0.height.equalTo(30)
$0.bottom.equalTo(safeArea)
}
descriptionLabel.textAlignment = .left
descriptionLabel.textColor = .label
descriptionLabel.font = .systemFont(ofSize: 15)
descriptionLabel.numberOfLines = 2
dropDownButton.setImage(UIImage(systemName: "chevron.down"), for: .normal)
dropDownButton.tintColor = .black
}
}
<TableViewCell ReusableProtocol>
protocol ReusableProtocol: AnyObject {
static var id: String { get }
}
extension UIView: ReusableProtocol {
static var id: String {
return String(describing: self)
}
}
1. ์ ๋์ด ์ค์
๊ธฐ๋ณธ ์
ํ
์ ์ด์ด์ ํด์ค์ผํ๋ ๋ถ๋ถ์ ๋ฒํผ์ ๋๋ ์ ๋,
descriptionLabel์ ๊ธธ์ด ๋งํผ ์ ๋์ ์ผ๋ก ์์ง์ผ ์ ์๋๋ก TableViewCell ๋์ด๋ฅผ ์ค์ ํด์ค์ผํฉ๋๋ค.
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
์ด๋ ๊ฒ ๋์ด ๊ฐ์ ํน์ ํด์ ์ ์ง ์๊ณ , UITableView.automaticDimension์ผ๋ก ์ ์ด์ฃผ๋ฉด ๋ฉ๋๋ค.
2. underDrop ๋ฒํผ ์ค์
TestTableViewCell ํ์ผ์์ ๋ง๋ค์๋ underDropButton์ ๋ํ action์ ์ถ๊ฐํด์ค๋๋ค. (addTarget)
class TestTableViewCell: UITableViewCell {
let descriptionLabel = UILabel()
let dropDownButton = UIButton()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
configureUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configureUI() {
...
dropDownButton.addTarget(self, action: #selector(dropDownButtonClicked), for: .touchUpInside)
}
@objc func dropDownButtonClicked() {
print("ํด๋ฆญ๋จ")
}
}
์์ฑ ํ, button์ ํด๋ฆญํ์ ๋, "ํด๋ฆญ๋จ"์ด ํ๋ฆฐํธ ๋๋์ง ํ์ธ!
3. ๋ฒํผ ์ํ ์ค์
๋ฒํผ์ ํด๋ฆญํ์ ๋, ํ๋ฒ ๋ ํด๋ฆญํ์ ๋,
์ํ๊ฐ ๊ณ์ ๋ณ๊ฒฝ๋์ด์ผ ํฉ๋๋ค. ๊ทธ๋์ toggle()์ ํ์ฉํด์ฃผ๋ ค๊ณ ํฉ๋๋ค.
var buttonState = false
์ฒ์ ์คํํ์ ๋๋ ์ ํ์๋ ์ํ์ฌ์ผํ๋, false๋ก ์ ์ธํด๋๊ฒ ์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ dropDownButtonClicked์ ํ์ํ ์ฝ๋๋ฅผ ์์ฑํ๊ฒ ์ต๋๋ค.
@objc func dropDownButtonClicked() {
buttonState.toggle()
if buttonState {
// descriptionLabel.text ์ ์ฒด ๊ธธ์ด๊ฐ ๋ชจ๋ ๋ณด์ผ ์ ์๋๋ก ์ค์
descriptionLabel.numberOfLines = 0
} else {
// ์ ์์ ๋, 2์ค๋ง ๋ณด์ผ ์ ์๋๋ก ์ค์
descriptionLabel.numberOfLines = 2
}
}
์ด๋ ๊ฒ ํด์ฃผ๊ณ ๋๋ฉด, ์ด์ Label์ ํ์ธ์ฉ์ผ๋ก ์์ฒญ ๊ธด ๋ฌธ์ฅ์ ๋ฃ์ด๋ด์ผ๊ฒ ์ฃ ?
์ ๋ '์์ด์ - Love Wins All' ๊ฐ์ฌ ์ผ๋ถ๋ฅผ ๊ฐ์ ธ์ค๊ฒ ์ต๋๋ค.
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: TestTableViewCell.id, for: indexPath) as? TestTableViewCell else { return UITableViewCell() }
cell.descriptionLabel.text = "Dearest, darling, my universe ๋ ๋ฐ๋ ค๊ฐ ์ค๋? ๋์ ์ด ๊ฐ๋ํ ์์๋ ฅ์ผ๋ก ๋ ์ฌ๋ฆด ์ ์๋ ๊ณณ์ผ๋ก ์ ๊ธฐ ๋ฉ๋ฆฌ from Earth to Mars ๊ผญ ๊ฐ์ด ๊ฐ์ค๋? ๊ทธ๊ณณ์ด ์ด๋๋ ์ค๋ ์ธ๋ก์, ๊ทธ ๋ฐ๋๋ง์ ์ฐพ์์ ์ด๋ค ์ค์๋ก ์ดํ ๋ก ์ฐ๋ฆฌ๋ ํจ๊ป์ผ๊น? ์ธ์์๊ฒ์ ๋๋ง์ณ run on ๋์ ์ ๋๊น์ง ๊ฐ์ค my lover ๋์ ๊ฒฐ๋ง์ผ๊น? ๊ธธ ์์ ์ฐ๋ฆฌ ๋ mm ๋ถ์์ง๋๋ก ๋๋ฅผ ๊ผญ ์์ ๋ ์ฌ๋ํ ๋ด๊ฒ ์
๋ง์ถฐ lover Love is all, love is all Love, love, love, love ๊ฒฐ๊ตญ, ๊ทธ๋ผ์๋ ์ด์งธ์ ์ฐ๋ฆฌ๋ ์๋ก์ผ๊น?"
return cell
}
}
4. TableView reload ํด์ฃผ๊ธฐ
View๋ ํ ๋ฒ ๊ทธ๋ ค์ง๊ณ ๋ ํ์ ๋ค์ ๊ทธ๋ ค๋ฌ๋ผ๊ณ ์์ฒญํ์ง ์์ผ๋ฉด, ๋ค์ ๊ทธ๋ ค์ง์ง ์์ต๋๋ค.
๊ทธ๋์ ์ ์ฝ๋์์ ์คํํ๊ฒ๋๋ฉด, ์๋ฌด๋ฐ ๋ณํ๊ฐ ์์๊ฒ๋๋ค.
๋ฒํผ์ ํด๋ฆญํ์ ๋! ์ํ๊ฐ ๋ณํํด์ผํ๋, ๋ฒํผ ํด๋ฆญ Action์์ reloadData๋ฅผ ํด์ฃผ๊ฒ ์ต๋๋ค.
var tableVew: UITableView?
์ฐ์ Cell ํ์ผ์์ ํ ์ด๋ธ ๋ทฐ๋ฅผ ๋ถ๋ฌ์ฌ ์ ์์ผ๋๊น ์ด๋ ๊ฒ ์ ์ธํด์ฃผ๊ณ ,
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: TestTableViewCell.id, for: indexPath) as? TestTableViewCell else { return UITableViewCell() }
cell.tableVew = tableView // ์ด๋ ๊ฒ
cell.descriptionLabel.text = "Dearest, darling, my universe ๋ ๋ฐ๋ ค๊ฐ ์ค๋? ๋์ ์ด ๊ฐ๋ํ ์์๋ ฅ์ผ๋ก ๋ ์ฌ๋ฆด ์ ์๋ ๊ณณ์ผ๋ก ์ ๊ธฐ ๋ฉ๋ฆฌ from Earth to Mars ๊ผญ ๊ฐ์ด ๊ฐ์ค๋? ๊ทธ๊ณณ์ด ์ด๋๋ ์ค๋ ์ธ๋ก์, ๊ทธ ๋ฐ๋๋ง์ ์ฐพ์์ ์ด๋ค ์ค์๋ก ์ดํ ๋ก ์ฐ๋ฆฌ๋ ํจ๊ป์ผ๊น? ์ธ์์๊ฒ์ ๋๋ง์ณ run on ๋์ ์ ๋๊น์ง ๊ฐ์ค my lover ๋์ ๊ฒฐ๋ง์ผ๊น? ๊ธธ ์์ ์ฐ๋ฆฌ ๋ mm ๋ถ์์ง๋๋ก ๋๋ฅผ ๊ผญ ์์ ๋ ์ฌ๋ํ ๋ด๊ฒ ์
๋ง์ถฐ lover Love is all, love is all Love, love, love, love ๊ฒฐ๊ตญ, ๊ทธ๋ผ์๋ ์ด์งธ์ ์ฐ๋ฆฌ๋ ์๋ก์ผ๊น?"
return cell
}
์ด๋ ๊ฒ ํ ๋นํด์ฃผ๊ฒ ์ต๋๋ค. (์ด์ ๋ณด๋,, tableView์ด๋ฆ์ ๋๋ฌด ์๋ฌด ์๊ฐ ์์ด ๋ง๋ค์ด๋จ๋ค์..ใ ใ ...)
@objc func dropDownButtonClicked() {
buttonState.toggle()
if buttonState {
descriptionLabel.numberOfLines = 0
} else {
descriptionLabel.numberOfLines = 2
}
tableVew?.reloadData() // ์ด๋ ๊ฒ
}
์ด๋ ๊ฒ ํ
์ด๋ธ๋ทฐ reloadData๋ฅผ ํด์ฃผ๋ฉด ๋์
๋๋ค!
์ ์ฒด ์ฝ๋๋ ์๋์ ์ ์๊ธ๋ก ๋ฃ์ด๋๊ฒ ์ต๋๋ค. :)๐
๊ฐ์ฌํฉ๋๋ค.๐๐ปโ๏ธ
<์ ์ฒด์ฝ๋>
<ViewController>
import UIKit
import SnapKit
class ViewController: UIViewController {
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
configureTableView()
}
func configureTableView() {
view.addSubview(tableView)
tableView.snp.makeConstraints {
$0.edges.equalTo(view.safeAreaLayoutGuide)
}
tableView.delegate = self
tableView.dataSource = self
tableView.register(TestTableViewCell.self, forCellReuseIdentifier: TestTableViewCell.id)
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 2
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: TestTableViewCell.id, for: indexPath) as? TestTableViewCell else { return UITableViewCell() }
cell.tableVew = tableView
cell.descriptionLabel.text = "Dearest, darling, my universe ๋ ๋ฐ๋ ค๊ฐ ์ค๋? ๋์ ์ด ๊ฐ๋ํ ์์๋ ฅ์ผ๋ก ๋ ์ฌ๋ฆด ์ ์๋ ๊ณณ์ผ๋ก ์ ๊ธฐ ๋ฉ๋ฆฌ from Earth to Mars ๊ผญ ๊ฐ์ด ๊ฐ์ค๋? ๊ทธ๊ณณ์ด ์ด๋๋ ์ค๋ ์ธ๋ก์, ๊ทธ ๋ฐ๋๋ง์ ์ฐพ์์ ์ด๋ค ์ค์๋ก ์ดํ ๋ก ์ฐ๋ฆฌ๋ ํจ๊ป์ผ๊น? ์ธ์์๊ฒ์ ๋๋ง์ณ run on ๋์ ์ ๋๊น์ง ๊ฐ์ค my lover ๋์ ๊ฒฐ๋ง์ผ๊น? ๊ธธ ์์ ์ฐ๋ฆฌ ๋ mm ๋ถ์์ง๋๋ก ๋๋ฅผ ๊ผญ ์์ ๋ ์ฌ๋ํ ๋ด๊ฒ ์
๋ง์ถฐ lover Love is all, love is all Love, love, love, love ๊ฒฐ๊ตญ, ๊ทธ๋ผ์๋ ์ด์งธ์ ์ฐ๋ฆฌ๋ ์๋ก์ผ๊น?"
return cell
}
}
<TestTableViewCell>
import UIKit
class TestTableViewCell: UITableViewCell {
let descriptionLabel = UILabel()
let dropDownButton = UIButton()
var buttonState = false
var tableVew: UITableView?
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
configureUI()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configureUI() {
contentView.addSubview(descriptionLabel)
contentView.addSubview(dropDownButton)
let safeArea = contentView.safeAreaLayoutGuide
descriptionLabel.snp.makeConstraints {
$0.top.equalTo(safeArea).offset(20)
$0.horizontalEdges.equalTo(safeArea).inset(20)
$0.bottom.equalTo(dropDownButton.snp.top).offset(-10)
}
dropDownButton.snp.makeConstraints {
$0.top.equalTo(descriptionLabel.snp.bottom)
$0.centerX.equalTo(safeArea)
$0.height.equalTo(30)
$0.bottom.equalTo(safeArea)
}
descriptionLabel.textAlignment = .left
descriptionLabel.textColor = .label
descriptionLabel.font = .systemFont(ofSize: 15)
descriptionLabel.numberOfLines = 2
dropDownButton.setImage(UIImage(systemName: "chevron.down"), for: .normal)
dropDownButton.tintColor = .black
dropDownButton.addTarget(self, action: #selector(dropDownButtonClicked), for: .touchUpInside)
}
@objc func dropDownButtonClicked() {
buttonState.toggle()
if buttonState {
descriptionLabel.numberOfLines = 0
} else {
descriptionLabel.numberOfLines = 2
}
tableVew?.reloadData()
}
}
<ReusableProtocol+>
import UIKit
protocol ReusableProtocol: AnyObject {
static var id: String { get }
}
extension UIView: ReusableProtocol {
static var id: String {
return String(describing: self)
}
}
'Swift' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Swift] CoreData - ๊ณต์๋ฌธ์ ํํค์น๊ธฐ (4) | 2024.12.01 |
---|---|
[Swift] ํ๋กํผํฐ(Property) โก - ํ์ (0) | 2024.06.04 |
[Swift] ํ๋กํผํฐ(Property) โ - ์ ์ฅ, ์ฐ์ฐ (0) | 2024.05.28 |
[Swift] for-in ๊ณผ forEach (0) | 2024.05.21 |
Swift ์ธ์ด๋? (0) | 2024.02.19 |