Skip to content

Commit cd1cbe1

Browse files
authored
Merge pull request #2195 from woocommerce/issue/2037-list-selector-updates
Update `ListSelectorViewController` for usage in products tab filtering
2 parents e0370fd + e974cfb commit cd1cbe1

16 files changed

+188
-185
lines changed

WooCommerce/Classes/ViewRelated/ListSelector/ListSelectorViewController.swift

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ import UIKit
22

33
/// A generic data source for the list selector UI `ListSelectorViewController`.
44
///
5-
protocol ListSelectorDataSource {
5+
protocol ListSelectorCommand {
66
associatedtype Model: Equatable
77
associatedtype Cell: UITableViewCell
8+
typealias ViewController = ListSelectorViewController<Self, Model, Cell>
9+
10+
/// Title of the navigation bar.
11+
var navigationBarTitle: String? { get }
812

913
/// A list of models to render the list.
1014
var data: [Model] { get }
@@ -13,7 +17,10 @@ protocol ListSelectorDataSource {
1317
var selected: Model? { get }
1418

1519
/// Called when a different model is selected.
16-
mutating func handleSelectedChange(selected: Model)
20+
/// - Parameters:
21+
/// - selected: the model that is selected by the user.
22+
/// - viewController: the list selector view controller.
23+
func handleSelectedChange(selected: Model, viewController: ViewController)
1724

1825
/// Configures the selected UI.
1926
func isSelected(model: Model) -> Bool
@@ -24,21 +31,18 @@ protocol ListSelectorDataSource {
2431

2532
/// Displays a list (implemented by table view) for the user to select a generic model.
2633
///
27-
final class ListSelectorViewController<DataSource: ListSelectorDataSource, Model, Cell>:
28-
UIViewController, UITableViewDataSource, UITableViewDelegate where DataSource.Model == Model, DataSource.Cell == Cell {
29-
private let viewProperties: ListSelectorViewProperties
30-
private var dataSource: DataSource
34+
final class ListSelectorViewController<Command: ListSelectorCommand, Model, Cell>:
35+
UIViewController, UITableViewDataSource, UITableViewDelegate where Command.Model == Model, Command.Cell == Cell {
36+
private let command: Command
3137
private let onDismiss: (_ selected: Model?) -> Void
3238

3339
private let rowType = Cell.self
3440

3541
@IBOutlet private weak var tableView: UITableView!
3642

37-
init(viewProperties: ListSelectorViewProperties,
38-
dataSource: DataSource,
43+
init(command: Command,
3944
onDismiss: @escaping (_ selected: Model?) -> Void) {
40-
self.viewProperties = viewProperties
41-
self.dataSource = dataSource
45+
self.command = command
4246
self.onDismiss = onDismiss
4347
super.init(nibName: "ListSelectorViewController", bundle: nil)
4448
}
@@ -56,29 +60,37 @@ UIViewController, UITableViewDataSource, UITableViewDelegate where DataSource.Mo
5660
}
5761

5862
override func viewWillDisappear(_ animated: Bool) {
59-
onDismiss(dataSource.selected)
63+
if isMovingFromParent {
64+
onDismiss(command.selected)
65+
}
6066
super.viewWillDisappear(animated)
6167
}
6268

69+
func reloadData() {
70+
tableView.reloadData()
71+
72+
title = command.navigationBarTitle
73+
}
74+
6375
// MARK: UITableViewDataSource
6476
//
6577
func numberOfSections(in tableView: UITableView) -> Int {
6678
return 1
6779
}
6880

6981
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
70-
return dataSource.data.count
82+
return command.data.count
7183
}
7284

7385
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
7486
guard let cell = tableView.dequeueReusableCell(withIdentifier: rowType.reuseIdentifier,
7587
for: indexPath) as? Cell else {
7688
fatalError()
7789
}
78-
let model = dataSource.data[indexPath.row]
79-
dataSource.configureCell(cell: cell, model: model)
90+
let model = command.data[indexPath.row]
91+
command.configureCell(cell: cell, model: model)
8092

81-
cell.accessoryType = dataSource.isSelected(model: model) ? .checkmark: .none
93+
cell.accessoryType = command.isSelected(model: model) ? .checkmark: .none
8294

8395
return cell
8496
}
@@ -88,9 +100,9 @@ UIViewController, UITableViewDataSource, UITableViewDelegate where DataSource.Mo
88100
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
89101
tableView.deselectRow(at: indexPath, animated: true)
90102

91-
let selected = dataSource.data[indexPath.row]
92-
if selected != dataSource.selected {
93-
dataSource.handleSelectedChange(selected: selected)
103+
let selected = command.data[indexPath.row]
104+
if selected != command.selected {
105+
command.handleSelectedChange(selected: selected, viewController: self)
94106
tableView.reloadData()
95107
}
96108
}
@@ -101,7 +113,7 @@ UIViewController, UITableViewDataSource, UITableViewDelegate where DataSource.Mo
101113
private extension ListSelectorViewController {
102114

103115
func configureNavigation() {
104-
title = viewProperties.navigationBarTitle
116+
title = command.navigationBarTitle
105117
}
106118

107119
func configureMainView() {

WooCommerce/Classes/ViewRelated/ListSelector/ListSelectorViewProperties.swift

Lines changed: 0 additions & 5 deletions
This file was deleted.

WooCommerce/Classes/ViewRelated/Products/Edit Product/Edit Price/ProductPriceSettingsViewController.swift

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,8 @@ extension ProductPriceSettingsViewController: UITableViewDelegate {
229229
viewModel.handleSaleEndDateChange(nil)
230230
refreshViewContent()
231231
case .taxStatus:
232-
let title = NSLocalizedString("Tax Status", comment: "Navigation bar title of the Product tax status selector screen")
233-
let viewProperties = ListSelectorViewProperties(navigationBarTitle: title)
234-
let dataSource = ProductTaxStatusListSelectorDataSource(selected: viewModel.taxStatus)
235-
let listSelectorViewController = ListSelectorViewController(viewProperties: viewProperties,
236-
dataSource: dataSource) { [weak self] selected in
232+
let command = ProductTaxStatusListSelectorCommand(selected: viewModel.taxStatus)
233+
let listSelectorViewController = ListSelectorViewController(command: command) { [weak self] selected in
237234
if let selected = selected {
238235
self?.viewModel.handleTaxStatusChange(selected)
239236
}

WooCommerce/Classes/ViewRelated/Products/Edit Product/Inventory Settings/ProductInventorySettingsViewController.swift

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -316,21 +316,15 @@ extension ProductInventorySettingsViewController: UITableViewDelegate {
316316

317317
switch rowAtIndexPath(indexPath) {
318318
case .stockStatus:
319-
let title = NSLocalizedString("Stock status", comment: "Product stock status list selector navigation title")
320-
let viewProperties = ListSelectorViewProperties(navigationBarTitle: title)
321-
let dataSource = ProductStockStatusListSelectorDataSource(selected: stockStatus)
322-
let listSelectorViewController = ListSelectorViewController(viewProperties: viewProperties,
323-
dataSource: dataSource) { [weak self] selected in
319+
let command = ProductStockStatusListSelectorCommand(selected: stockStatus)
320+
let listSelectorViewController = ListSelectorViewController(command: command) { [weak self] selected in
324321
self?.stockStatus = selected
325322
self?.tableView.reloadData()
326323
}
327324
navigationController?.pushViewController(listSelectorViewController, animated: true)
328325
case .backorders:
329-
let title = NSLocalizedString("Backorders", comment: "Product backorders setting list selector navigation title")
330-
let viewProperties = ListSelectorViewProperties(navigationBarTitle: title)
331-
let dataSource = ProductBackordersSettingListSelectorDataSource(selected: backordersSetting)
332-
let listSelectorViewController = ListSelectorViewController(viewProperties: viewProperties,
333-
dataSource: dataSource) { [weak self] selected in
326+
let command = ProductBackordersSettingListSelectorCommand(selected: backordersSetting)
327+
let listSelectorViewController = ListSelectorViewController(command: command) { [weak self] selected in
334328
self?.backordersSetting = selected
335329
self?.tableView.reloadData()
336330
}

WooCommerce/Classes/ViewRelated/Products/Edit Product/List Selector Data Source/ProductBackordersSettingListSelectorDataSource.swift renamed to WooCommerce/Classes/ViewRelated/Products/Edit Product/List Selector Data Source/ProductBackordersSettingListSelectorCommand.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import UIKit
22
import Yosemite
33

4-
/// `ListSelectorDataSource` for selecting a Product Backorders Setting.
4+
/// `ListSelectorCommand` for selecting a Product Backorders Setting.
55
///
6-
struct ProductBackordersSettingListSelectorDataSource: ListSelectorDataSource {
6+
final class ProductBackordersSettingListSelectorCommand: ListSelectorCommand {
77
typealias Model = ProductBackordersSetting
88
typealias Cell = BasicTableViewCell
99

10+
let navigationBarTitle: String? = NSLocalizedString("Backorders", comment: "Product backorders setting list selector navigation title")
11+
1012
let data: [ProductBackordersSetting] = [
1113
.notAllowed,
1214
.allowedAndNotifyCustomer,
@@ -24,7 +26,7 @@ struct ProductBackordersSettingListSelectorDataSource: ListSelectorDataSource {
2426
cell.textLabel?.text = model.description
2527
}
2628

27-
mutating func handleSelectedChange(selected: ProductBackordersSetting) {
29+
func handleSelectedChange(selected: ProductBackordersSetting, viewController: ViewController) {
2830
self.selected = selected
2931
}
3032

WooCommerce/Classes/ViewRelated/Products/Edit Product/List Selector Data Source/ProductStockStatusListSelectorDataSource.swift renamed to WooCommerce/Classes/ViewRelated/Products/Edit Product/List Selector Data Source/ProductStockStatusListSelectorCommand.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import UIKit
22
import Yosemite
33

4-
/// `ListSelectorDataSource` for selecting a Product Stock Status.
4+
/// `ListSelectorCommand` for selecting a Product Stock Status.
55
///
6-
struct ProductStockStatusListSelectorDataSource: ListSelectorDataSource {
6+
final class ProductStockStatusListSelectorCommand: ListSelectorCommand {
77
typealias Model = ProductStockStatus
88
typealias Cell = BasicTableViewCell
99

10+
let navigationBarTitle: String? = NSLocalizedString("Stock status", comment: "Product stock status list selector navigation title")
11+
1012
let data: [ProductStockStatus] = [
1113
.inStock,
1214
.outOfStock,
@@ -24,7 +26,7 @@ struct ProductStockStatusListSelectorDataSource: ListSelectorDataSource {
2426
cell.textLabel?.text = model.description
2527
}
2628

27-
mutating func handleSelectedChange(selected: ProductStockStatus) {
29+
func handleSelectedChange(selected: ProductStockStatus, viewController: ViewController) {
2830
self.selected = selected
2931
}
3032

WooCommerce/Classes/ViewRelated/Products/Edit Product/List Selector Data Source/ProductTaxStatusListSelectorDataSource.swift renamed to WooCommerce/Classes/ViewRelated/Products/Edit Product/List Selector Data Source/ProductTaxStatusListSelectorCommand.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import UIKit
22
import Yosemite
33

4-
/// `ListSelectorDataSource` for selecting a Product Tax Status.
4+
/// `ListSelectorCommand` for selecting a Product Tax Status.
55
///
6-
struct ProductTaxStatusListSelectorDataSource: ListSelectorDataSource {
6+
final class ProductTaxStatusListSelectorCommand: ListSelectorCommand {
77
typealias Model = ProductTaxStatus
88
typealias Cell = BasicTableViewCell
99

10+
let navigationBarTitle: String? = NSLocalizedString("Tax Status", comment: "Navigation bar title of the Product tax status selector screen")
11+
1012
let data: [ProductTaxStatus] = [
1113
.taxable,
1214
.shipping,
@@ -24,7 +26,7 @@ struct ProductTaxStatusListSelectorDataSource: ListSelectorDataSource {
2426
cell.textLabel?.text = model.description
2527
}
2628

27-
mutating func handleSelectedChange(selected: ProductTaxStatus) {
29+
func handleSelectedChange(selected: ProductTaxStatus, viewController: ViewController) {
2830
self.selected = selected
2931
}
3032

WooCommerce/Classes/ViewRelated/Products/Edit Product/Product Settings/List Selector Data Source/ProductStatusSettingListSelectorDataSource.swift renamed to WooCommerce/Classes/ViewRelated/Products/Edit Product/Product Settings/List Selector Data Source/ProductStatusSettingListSelectorCommand.swift

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import UIKit
22
import Yosemite
33

4-
/// `ListSelectorDataSource` for selecting a Product Status Setting.
4+
/// `ListSelectorCommand` for selecting a Product Status Setting.
55
///
6-
struct ProductStatusSettingListSelectorDataSource: ListSelectorDataSource {
6+
final class ProductStatusSettingListSelectorCommand: ListSelectorCommand {
77
typealias Model = ProductStatus
88
typealias Cell = BasicTableViewCell
99

10+
let navigationBarTitle: String? = NSLocalizedString("Status", comment: "Product status setting list selector navigation title")
11+
1012
let data: [ProductStatus] = [
1113
.publish,
1214
.draft,
@@ -25,7 +27,7 @@ struct ProductStatusSettingListSelectorDataSource: ListSelectorDataSource {
2527
cell.textLabel?.text = model.description
2628
}
2729

28-
mutating func handleSelectedChange(selected: ProductStatus) {
30+
func handleSelectedChange(selected: ProductStatus, viewController: ViewController) {
2931
self.selected = selected
3032
}
3133

WooCommerce/Classes/ViewRelated/Products/Edit Product/Product Settings/ProductSettingsRows.swift

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,9 @@ enum ProductSettingsRows {
4444
}
4545

4646
func handleTap(sourceViewController: UIViewController, onCompletion: @escaping (ProductSettings) -> Void) {
47-
let title = NSLocalizedString("Status", comment: "Product status setting list selector navigation title")
48-
let viewProperties = ListSelectorViewProperties(navigationBarTitle: title)
49-
let dataSource = ProductStatusSettingListSelectorDataSource(selected: settings.status)
47+
let command = ProductStatusSettingListSelectorCommand(selected: settings.status)
5048

51-
let listSelectorViewController = ListSelectorViewController(viewProperties: viewProperties,
52-
dataSource: dataSource) { selected in
49+
let listSelectorViewController = ListSelectorViewController(command: command) { selected in
5350

5451
self.settings.status = selected ?? self.settings.status
5552
onCompletion(self.settings)

0 commit comments

Comments
 (0)