
캘린더 앱을 실행했을 때 이동시간, 반복, 알림과 같이 cell의 accessoryView에 Pull Down Button을 추가하는 작업


.none이며 액세서리가 없음.| accessoryType | accessory | 설명 |
|---|---|---|
| .none | 액세서리 없음 | 기본값 |
| .disclosureIndicator | > | 다음 View로 이동하는 Cell에 사용 |
| .detailDisclosureButton | ℹ️ > | 탭하여 이벤트 가능 |
| .checkmark | ☑️ | |
| .detailButton | ℹ️ | 이벤트 가능하며 detailDisclosureButton와 다름 |
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.font = UIFont.preferredFont(forTextStyle: .body)
switch indexPath.section {
case 0:
switch indexPath.row {
case 0:
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row].title
cell.accessoryType = .none
case 1:
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row].title
cell.accessoryType = .disclosureIndicator
case 2:
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row].title
cell.accessoryType = .detailDisclosureButton
case 3:
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row].title
cell.accessoryType = .checkmark
case 4:
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row].title
cell.accessoryType = .detailButton
default: break
}
}
return cell
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") ?? UITableViewCell(style: .default, reuseIdentifier: "Cell")
cell.textLabel?.font = UIFont.preferredFont(forTextStyle: .body)
switch indexPath.section {
case 1:
switch indexPath.row {
case 0:
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row].title
cell.accessoryView = PullDownButton(configModel: pullDownOption, keyPath: \.data, options: dataOptions)
case 1:
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row].title
cell.accessoryView = PullDownButton(configModel: pullDownOption, keyPath: \.style, options: styleOptions)
case 2:
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row].title
cell.accessoryView = PullDownButton(configModel: pullDownOption, keyPath: \.type, options: typeOptions)
default:
cell.textLabel?.text = sections[indexPath.section].items[indexPath.row].title
cell.accessoryView = nil
}
default: break
}
return cell
}
class PullDownButton<T>: UIButton {
private var keyPath: WritableKeyPath<PullDownOption, T>!
private var configModel: PullDownOption!
init(configModel: PullDownOption, keyPath: WritableKeyPath<PullDownOption, T>, options: [T]) {
super.init(frame: .zero)
self.configModel = configModel
self.keyPath = keyPath
self.showsMenuAsPrimaryAction = true
self.tintColor = .systemGray
self.contentHorizontalAlignment = .trailing
self.titleLabel?.font = UIFont.preferredFont(forTextStyle: .body)
updateTitle(with: configModel[keyPath: keyPath])
self.menu = UIMenu(children: options.map { option in
UIAction(title: "\(option)") { [weak self] _ in
guard let self = self else { return }
self.configModel[keyPath: self.keyPath] = option
self.updateTitle(with: option)
}
})
self.sizeToFit()
self.frame.size = CGSize(width: max(self.frame.width, 80), height: max(self.frame.height, 30))
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func updateTitle(with value: T) {
let image = UIImage(systemName: "chevron.up.chevron.down")!
let attributedString = NSMutableAttributedString(string: "\(value) ")
let attachment = NSTextAttachment()
attachment.image = image.withRenderingMode(.alwaysTemplate)
attributedString.append(NSAttributedString(attachment: attachment))
attributedString.addAttribute(.foregroundColor, value: UIColor.systemGray, range: NSRange(location: 0, length: attributedString.length))
self.setAttributedTitle(attributedString, for: .normal)
self.sizeToFit()
}
}
private var keyPath: WritableKeyPath<PullDownOption, T>!
private var configModel: PullDownOption!
self.configModel[keyPath: self.keyPath] = option

PullDownButton
https://github.com/zongbeen/AboutiOS/blob/main/AboutiOS/Component/PullDownButton.swift
