// // TableViewTestController.swift // VDSSample // // Created by Matt Bruce on 5/3/23. // import Foundation import UIKit import VDS import VDSColorTokens public typealias TestView = UIView & Surfaceable public typealias TestViewWrapper = (component: TestView, isTrailing: Bool) protocol Componentable { static func getComponent() -> TestViewWrapper } public class TableViewTestController: UITableViewController, Initable, Surfaceable { var components:[TestViewWrapper] = [] public var surface: Surface = .light { didSet { tableView.reloadData() } } //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- required public init() { super.init(nibName: nil, bundle: nil) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } public override func viewDidLoad() { super.viewDidLoad() MenuViewController.items.forEach { menuItem in if let componentable = menuItem.viewController as? Componentable.Type { components.append(componentable.getComponent()) } } tableView.register(VDSCell.self, forCellReuseIdentifier: "cell") tableView.allowsSelection = false tableView.estimatedRowHeight = 100 tableView.separatorStyle = .none tableView.rowHeight = UITableView.automaticDimension tableView.reloadData() let view = View(frame: .init(origin: .zero, size: .init(width: tableView.bounds.width, height: 100))) let toggle = Toggle().with { $0.showText = true $0.textPosition = .right $0.offText = "Light" $0.onText = "Dark" $0.onChange = { [weak self] toggle in self?.surface = toggle.isOn ? .dark : .light } } view.addSubview(toggle) toggle.pinToSuperView(.init(top: 5, left: 16, bottom: 5, right: 16)) tableView.tableHeaderView = view tableView.tableHeaderView?.frame.size.height = 40 } public override func numberOfSections(in tableView: UITableView) -> Int { components.count } public override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { let header = UIView().with { $0.backgroundColor = VDSColor.paletteGray44 } let label = Label().with { $0.text = "\(type(of: components[section].component))" $0.surface = .dark $0.textStyle = .boldTitleSmall } header.addSubview(label) label.pinTrailing(16) label.pinLeading(16) label.centerYAnchor.constraint(equalTo: header.centerYAnchor).activate() return header } public override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 40 } public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 1 } public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as? VDSCell else { return UITableViewCell() } cell.prepareForReuse() cell.surface = surface let wrapper = components[indexPath.section] cell.component = wrapper.component cell.isTrailing = wrapper.isTrailing return cell } } public class VDSCell: UITableViewCell, AppleGuidlinesTouchable, Surfaceable { public var isTrailing: Bool = true public var surface: Surface = .light public var component: TestView? { didSet { contentView.subviews.forEach { $0.removeFromSuperview() } guard var component else { return } let wrapper = UIView.makeWrapper(for: component, isTrailing: isTrailing) contentView.addSubview(wrapper) wrapper.pinToSuperView(.init(top: 16, left: 16, bottom: 16, right: 16)) backgroundColor = surface.color component.surface = surface } } override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool { Self.acceptablyOutsideBounds(point: point, bounds: bounds) } public override var intrinsicContentSize: CGSize { guard let component else { return .zero } return component.intrinsicContentSize } }