Skip to content

Commit

Permalink
feat(ListViewCell): Refactor ListViewCell as independent view for Tab…
Browse files Browse the repository at this point in the history
…leView and CollectionView

BREAKING CHANGE: ListViewCell has been independently refactored as a UIView. What we used to use as ListViewCell is now ListTableViewCell for ListTableViews. It has also been exposed as ListCollectionViewCell for CollectionViews.
  • Loading branch information
alejandroruizponce authored Mar 2, 2023
1 parent 516e316 commit 4a8704b
Show file tree
Hide file tree
Showing 20 changed files with 498 additions and 166 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ private enum Constants {
}

public class UICatalogCardsViewController: UIViewController {
private let tableView = ListView()
private let tableView = ListTableView()

public init() {
super.init(nibName: nil, bundle: nil)
Expand Down Expand Up @@ -51,13 +51,13 @@ extension UICatalogCardsViewController: UITableViewDataSource, UITableViewDelega
}

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Constants.cellReusableIdentifier, for: indexPath) as! ListViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: Constants.cellReusableIdentifier, for: indexPath) as! ListTableViewCell

let catalogRow = UICardRow(rawValue: indexPath.row)!

cell.title = catalogRow.title
cell.assetType = .smallIcon(catalogRow.icon)
cell.controlView = NavigationPresetView()
cell.listCellContentView.title = catalogRow.title
cell.listCellContentView.assetType = .smallIcon(catalogRow.icon)
cell.listCellContentView.controlView = NavigationPresetView()

return cell
}
Expand Down Expand Up @@ -93,7 +93,7 @@ private extension UICatalogCardsViewController {

tableView.dataSource = self
tableView.delegate = self
tableView.register(ListViewCell.self, forCellReuseIdentifier: Constants.cellReusableIdentifier)
tableView.register(ListCellContentView.self, forCellReuseIdentifier: Constants.cellReusableIdentifier)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ extension UICatalogListsViewController {

switch assetStyleCell.segmentedControl.selectedSegmentIndex {
case 0:
sampleVC.assetType = ListViewCell.CellAssetType.none
sampleVC.assetType = ListCellContentView.CellAssetType.none
case 1:
sampleVC.assetType = .largeIcon(.imageIcon, backgroundColor: .neutralLow)
case 2:
Expand Down Expand Up @@ -219,23 +219,23 @@ private class UICatalogListSampleViewController: UIViewController, UITableViewDa
case custom
}

private let listView = ListView()
private let listTableView = ListTableView()

var text: String?
var detailText: String?
var subtitle: String?
var showHeadline: Bool = false
var assetType: ListViewCell.CellAssetType!
var assetType: ListCellContentView.CellAssetType!
var customControl = CustomControl.none
var cellLayoutStyle: ListViewCell.CellStyle!
var cellLayoutStyle: ListCellContentView.CellStyle!

let numberOfRows = 30

override func loadView() {
let view = UIView()
view.backgroundColor = .background

view.addSubview(withDefaultConstraints: listView)
view.addSubview(withDefaultConstraints: listTableView)

self.view = view
}
Expand All @@ -244,39 +244,39 @@ private class UICatalogListSampleViewController: UIViewController, UITableViewDa
super.viewDidLoad()

navigationItem.largeTitleDisplayMode = .never
listView.dataSource = self
ListViewCell.register(on: listView)
listTableView.dataSource = self
ListTableViewCell.register(on: listTableView)
}

func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int {
numberOfRows
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = ListViewCell.dequeueReusableCell(for: indexPath, from: tableView)
let cell = ListTableViewCell.dequeueReusableCell(for: indexPath, from: tableView)

cell.title = text
cell.subtitle = subtitle
cell.detailText = detailText
cell.assetType = assetType
cell.subtitle = subtitle
cell.cellStyle = cellLayoutStyle
cell.listCellContentView.title = text
cell.listCellContentView.subtitle = subtitle
cell.listCellContentView.detailText = detailText
cell.listCellContentView.assetType = assetType
cell.listCellContentView.subtitle = subtitle
cell.listCellContentView.cellStyle = cellLayoutStyle

if showHeadline {
cell.headlineView = TagView(text: "HEADLINE")
cell.listCellContentView.headlineView = TagView(text: "HEADLINE")
}

switch customControl {
case .none:
cell.controlView = nil
cell.listCellContentView.controlView = nil
case .navigation:
let navigationPreset = NavigationPresetView()
navigationPreset.isBadgeHidden = false
navigationPreset.badgeView.style = .numeric
navigationPreset.badgeView.value = Int.random(in: 1 ... 10)
cell.controlView = navigationPreset
cell.listCellContentView.controlView = navigationPreset
case .custom:
cell.controlView = CustomPresetView()
cell.listCellContentView.controlView = CustomPresetView()
}

cell.isCellSeparatorHidden = indexPath.row == (numberOfRows - 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class UICatalogSectionTitleViewController: UITableViewController {
tableView.tableFooterView = UIView(frame: CGRect.zero)
tableView.sectionFooterHeight = 0.0

tableView.register(ListViewCell.self, forCellReuseIdentifier: Constants.listCellReusableIdentifier)
tableView.register(ListCellContentView.self, forCellReuseIdentifier: Constants.listCellReusableIdentifier)
tableView.register(TitleView.self, forHeaderFooterViewReuseIdentifier: Constants.sectionTitleReusableIdentifier)
}

Expand All @@ -65,9 +65,9 @@ class UICatalogSectionTitleViewController: UITableViewController {
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Constants.listCellReusableIdentifier, for: indexPath) as! ListViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: Constants.listCellReusableIdentifier, for: indexPath) as! ListTableViewCell

cell.title = "Lorem ipsum dolor sit amet"
cell.listCellContentView.title = "Lorem ipsum dolor sit amet"
cell.isCellSeparatorHidden = indexPath.section == 2 && indexPath.row == 1

return cell
Expand Down
2 changes: 1 addition & 1 deletion Sources/Mistica/Components/Lists/CellStyle+Toolkit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation

import UIKit

extension ListViewCell.CellStyle {
extension ListCellContentView.CellStyle {
var cornerRadius: CGFloat {
switch self {
case .fullWidth:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CellLeftSectionView: UIStackView {

private let imageView = IntrinsictImageView()

var assetType: ListViewCell.CellAssetType = .none {
var assetType: ListCellContentView.CellAssetType = .none {
didSet {
heightConstraint.constant = assetType.viewSize
widthConstraint.constant = assetType.viewSize
Expand Down Expand Up @@ -83,7 +83,7 @@ private extension CellLeftSectionView {
}
}

private extension ListViewCell.CellAssetType {
private extension ListCellContentView.CellAssetType {
var assetSize: CGFloat {
switch self {
case .none:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// ListViewCell.swift
// ListCellContentView.swift
//
// Made with ❤️ by Novum
//
Expand All @@ -8,15 +8,20 @@

import UIKit

// MARK: View Styles

private enum ViewStyles {
static let horizontalPadding: CGFloat = 16
protocol ListCellContentTableViewDelegate {
func cellStyleChanged()
}

// MARK: ListViewCell
// MARK: ListCellContentView

open class ListCellContentView: UIView {
// MARK: View Styles

public enum ViewStyles {
static let horizontalPadding: CGFloat = 16.0
static let cellWidth: CGFloat = 324.0
}

open class ListViewCell: UITableViewCell {
@frozen
public enum CellStyle {
case fullWidth
Expand All @@ -32,29 +37,14 @@ open class ListViewCell: UITableViewCell {
case largeIcon(UIImage, backgroundColor: UIColor)
}

// MARK: Initializers

override public init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)

commonInit()
}

public required init?(coder: NSCoder) {
super.init(coder: coder)

commonInit()
}

// MARK: SubViews

/// View used in `ListCellStyle.boxed` style for show a rounded border arround the content
private lazy var cellBorderView = UIView()
lazy var cellBorderView = UIView()
private lazy var cellContentView = UIStackView()
/// A cell separator visible only in` ListCellStyle.fullWidth`
private lazy var cellSeparatorView = SeparatorView(axis: .horizontal)
var tableViewDelegate: ListCellContentTableViewDelegate?
private lazy var leftSection = CellLeftSectionView()
private lazy var centerSection = CellCenterSectionView()
lazy var centerSection = CellCenterSectionView()

// MARK: Public

Expand Down Expand Up @@ -191,56 +181,25 @@ open class ListViewCell: UITableViewCell {
}
}

public var isCellSeparatorHidden: Bool = true {
didSet {
guard cellStyle != .boxed && cellStyle != .boxedInverse else { return }

cellSeparatorView.isHidden = isCellSeparatorHidden
}
}

// MARK: UITableViewCell Overrides

override public func systemLayoutSizeFitting(_ targetSize: CGSize,
withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority,
verticalFittingPriority: UILayoutPriority) -> CGSize {
let size = super.systemLayoutSizeFitting(
targetSize,
withHorizontalFittingPriority: horizontalFittingPriority,
verticalFittingPriority: verticalFittingPriority
)

return CGSize(width: size.width, height: max(size.height, cellStyle.minHeight))
}

override public func setHighlighted(_ highlighted: Bool, animated _: Bool) {
if highlighted {
highlightedView.backgroundColor = .backgroundAlternative
} else {
highlightedView.backgroundColor = .backgroundContainer
}
convenience init() {
self.init(frame: .zero)
}

override public func setSelected(_: Bool, animated _: Bool) {
// Do nothing
}
override init(frame _: CGRect) {
super.init(frame: .zero)

override open var isUserInteractionEnabled: Bool {
didSet {
centerSection.isUserInteractionEnabled = isUserInteractionEnabled
}
commonInit()
}

override open func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
guard traitCollection.userInterfaceStyle != previousTraitCollection?.userInterfaceStyle else { return }
cellBorderView.layer.borderColor = cellStyle.borderColor
@available(*, unavailable)
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}

// MARK: Custom Accessibilities

public extension ListViewCell {
public extension ListCellContentView {
var titleAccessibilityLabel: String? {
get {
centerSection.titleLabel.accessibilityLabel
Expand Down Expand Up @@ -316,41 +275,21 @@ public extension ListViewCell {

// MARK: Private

private extension ListViewCell {
var highlightedView: UIView {
switch cellStyle {
case .fullWidth, .boxedInverse:
return contentView
case .boxed:
return cellBorderView
}
}

private extension ListCellContentView {
func commonInit() {
layoutViews()
updateCellStyle()
}

func layoutViews() {
contentView.addSubview(constrainedToLayoutMarginsGuideOf: cellBorderView)
contentView.addSubview(constrainedToLayoutMarginsGuideOf: cellContentView)

contentView.addSubview(cellSeparatorView, constraints: [
cellSeparatorView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
cellSeparatorView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -ViewStyles.horizontalPadding),
cellSeparatorView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: ViewStyles.horizontalPadding),
cellSeparatorView.centerXAnchor.constraint(equalTo: contentView.centerXAnchor)
])
addSubview(constrainedToLayoutMarginsGuideOf: cellBorderView)
addSubview(constrainedToLayoutMarginsGuideOf: cellContentView)

cellContentView.addArrangedSubview(centerSection)
cellContentView.spacing = ViewStyles.horizontalPadding
}

func updateCellStyle() {
contentView.directionalLayoutMargins = cellStyle.contentViewLayoutMargins
contentView.preservesSuperviewLayoutMargins = false
contentView.backgroundColor = .background

centerSection.titleTextColor = cellStyle.titleTextColor
centerSection.subtitleTextColor = cellStyle.subtitleTextColor

Expand All @@ -362,11 +301,11 @@ private extension ListViewCell {
cellBorderView.layer.borderColor = cellStyle.borderColor
cellBorderView.layer.borderWidth = cellStyle.borderWidth

cellSeparatorView.isHidden = cellStyle.cellSeparatorIsHidden

if cellStyle == .boxedInverse {
controlView?.tintColor = .white
}

tableViewDelegate?.cellStyleChanged()
}

func updateAssetView() {
Expand Down
Loading

0 comments on commit 4a8704b

Please sign in to comment.