Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- rxswift
- map
- UITextView
- RxCocoa
- Protocol
- UICollectionView
- Xcode
- HIG
- Observable
- ribs
- uitableview
- swiftUI
- 리팩토링
- ios
- Clean Code
- swift documentation
- MVVM
- 클린 코드
- SWIFT
- clean architecture
- combine
- 리펙토링
- 스위프트
- Refactoring
- Human interface guide
- uiscrollview
- tableView
- 리펙터링
- collectionview
- 애니메이션
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] UITableViewCell에 pressed 효과 주는 방법 (highlighted 효과, pressed 효과) 본문
iOS 응용 (swift)
[iOS - swift] UITableViewCell에 pressed 효과 주는 방법 (highlighted 효과, pressed 효과)
jake-kim 2024. 10. 24. 01:42UITableViewCell의 pressed 효과
- 기대하는 pressed 효과 (이 화면은 pressed 효과를 직접 구현한 화면)
- UIButton의 highlighted 효과처럼 동작
- 하지만 위처럼 동작하려면 별도 구현이 필요하고, 디폴트는 이렇게 동작됨
- 단, selectionStyle = .none으로 한 상태
코드)
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
tableView.frame = view.bounds
tableView.dataSource = self
tableView.delegate = self
view.addSubview(tableView)
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "CustomCell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomTableViewCell
cell.myLabel.text = "Row \(indexPath.row)"
return cell
}
}
class CustomTableViewCell: UITableViewCell {
private enum Const {
static let backgroundColor = UIColor.white
static let pressedColor = UIColor.gray
}
let myLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = .black
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
selectionStyle = .none
contentView.addSubview(myLabel)
NSLayoutConstraint.activate([
myLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
myLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16)
])
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
pressed 효과 주는 방법
- 우선 커스텀 셀에 setHighlighted를 오버라이딩하여 backgroundColor를 변경
class CustomTableViewCell: UITableViewCell {
...
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
contentView.backgroundColor = highlighted ? Const.pressedColor : Const.backgroundColor
}
...
}
결과)
- long pressed 한 상태에서만 색상이 변경됨
- UIButton과 다르게 UITableViewCell은 setHighlighted 호출 시점이 long pressed 시점
- 터치했을때도 pressed 효과가 발동해야하므로 didSelectRowAt 델리게이트 함수에서 별도로 pressed 효과를 발생시키기
- 커스텀 셀 내부에 pressed 애니메이션 구현
class CustomTableViewCell: UITableViewCell {
...
func animatePressed(completion: @escaping () ->()) {
contentView.backgroundColor = Const.pressedColor
UIView.animate(withDuration: 0.3, animations: {
self.contentView.backgroundColor = Const.backgroundColor
self.layoutIfNeeded()
}, completion: { _ in
completion()
})
}
...
}
- 이 함수를 didSelectRowAt에서 호출
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
...
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
(tableView.cellForRow(at: indexPath) as? CustomTableViewCell)?.animatePressed {
// no-op
}
}
}
완성)
전체 코드)
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
let tableView = UITableView()
override func viewDidLoad() {
super.viewDidLoad()
tableView.frame = view.bounds
tableView.dataSource = self
tableView.delegate = self
view.addSubview(tableView)
tableView.register(CustomTableViewCell.self, forCellReuseIdentifier: "CustomCell")
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
10
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomTableViewCell
cell.myLabel.text = "Row \(indexPath.row)"
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
(tableView.cellForRow(at: indexPath) as? CustomTableViewCell)?.animatePressed {
// no-op
}
}
}
class CustomTableViewCell: UITableViewCell {
private enum Const {
static let backgroundColor = UIColor.white
static let pressedColor = UIColor.gray
}
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
super.setHighlighted(highlighted, animated: animated)
contentView.backgroundColor = highlighted ? Const.pressedColor : Const.backgroundColor
}
let myLabel: UILabel = {
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.textColor = .black
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
selectionStyle = .none
contentView.addSubview(myLabel)
NSLayoutConstraint.activate([
myLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
myLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16)
])
}
func animatePressed(completion: @escaping () ->()) {
contentView.backgroundColor = Const.pressedColor
UIView.animate(withDuration: 0.3, animations: {
self.contentView.backgroundColor = Const.backgroundColor
self.layoutIfNeeded()
}, completion: { _ in
completion()
})
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
'iOS 응용 (swift)' 카테고리의 다른 글
[iOS - swift] @retroactive 개념 (Swift6, Xcode16) (0) | 2024.12.02 |
---|---|
[iOS - swift] UIPasteBoard.general.changeCount (복사했는지 확인 방법) (1) | 2024.11.12 |
[iOS - swift] 디스플레이 확대/축소 옵션 대응 방법 (UIScreen.main.nativeScale) (0) | 2024.10.18 |
[iOS - swift] CoreHaptics (진동 주는 방법, 진동 효과) (6) | 2024.10.09 |
[iOS - swift] DispatchQueue 작업 취소, 작업 예약 방법 (DispatchSourceTimer, makeTimerSource, 일시 정지 타이머) (0) | 2024.10.07 |
Comments