import UIKit // MARK: - 目录面板 /// EPUB 阅读器的目录面板控制器 /// 以列表形式展示书籍目录,支持多级缩进,当前所在章节高亮显示 final class RDEPUBReaderChapterListController: UITableViewController { /// 用户选择目录项时的回调 var onSelectItem: ((RDEPUBReaderTableOfContentsItem) -> Void)? private let items: [RDEPUBReaderTableOfContentsItem] private let currentItem: RDEPUBReaderTableOfContentsItem? private let theme: RDEPUBReaderTheme init( items: [RDEPUBReaderTableOfContentsItem], currentItem: RDEPUBReaderTableOfContentsItem?, theme: RDEPUBReaderTheme ) { self.items = items self.currentItem = currentItem self.theme = theme super.init(style: .plain) title = "目录" } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func viewDidLoad() { super.viewDidLoad() view.accessibilityIdentifier = "epub.reader.toc.panel" tableView.accessibilityIdentifier = "epub.reader.toc.table" tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") tableView.tableFooterView = UIView(frame: .zero) tableView.backgroundColor = theme.contentBackgroundColor navigationController?.navigationBar.tintColor = theme.toolControlTextColor navigationController?.navigationBar.barTintColor = theme.toolBackgroundColor navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: theme.toolControlTextColor] navigationController?.navigationBar.accessibilityIdentifier = "epub.reader.toc.navbar" } override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { items.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let item = items[indexPath.row] let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) cell.backgroundColor = theme.contentBackgroundColor cell.textLabel?.numberOfLines = 2 cell.textLabel?.text = item.title cell.textLabel?.textColor = isCurrentItem(item) ? .systemBlue : theme.contentTextColor cell.indentationLevel = item.depth cell.indentationWidth = 18 return cell } override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { onSelectItem?(items[indexPath.row]) } private func isCurrentItem(_ item: RDEPUBReaderTableOfContentsItem) -> Bool { guard let currentItem else { return false } return currentItem.href == item.href } }