Reputation: 16456
I am stuck in situation where I could not able to find solution. Seen many similar question but could't able to figure it out.
So I have one View Controller which shows table view list for two types
1) Sales
2) Purchase
And I have decided to use same View Controller for both
enum SalesRowType {
case salesOrderBooking
case salesInvoicing
case salesGrossContribution
}
enum PurchaseRowType {
case purchaseOrders
case amended_non_amended
case pending_grn_po
}
and
// BASE PROTOCOL
// ListRowType -> has title,image property
protocol HomeSubItemType:ListRowType {
associatedtype RowType
var type:RowType {get}
}
// PURCHASE ITEMS
struct PurchaseSubItem: HomeSubItemType {
typealias RowType = PurchaseRowType
var image: UIImage
var title: String
var type: PurchaseRowType
}
// SALES ITEMS
struct SalesSubItem : HomeSubItemType {
var image:UIImage
var title:String
var type:SalesRowType
}
In My View Controller I want to create array as per sales and purchase
if let type = type {
switch type {
case .purchase:
self.title = "Purchase"
self.itemList = [
PurchaseSubItem(image: UIImage(named: "purchase-orders")!, title: "Purchase Orders", type: .purchaseOrders),
PurchaseSubItem(image: UIImage(named: "amended-non")!, title: "Amended/NON-Amended-UNAutho-PO", type: .purchaseOrders),
PurchaseSubItem(image: UIImage(named: "purchase-pending")!, title: "Pending GRN PO", type: .purchaseOrders)]
case .sales:
self.title = "Sales"
self.itemList =
[
SalesSubItem(image: UIImage(named: "sales-order-booking")!, title: "Sales Order Booking", type: .salesOrderBooking),
SalesSubItem(image: UIImage(named: "sales-invoice")!, title: "Sales Invoicing", type: .salesInvoicing),
SalesSubItem(image: UIImage(named: "sale-gross")!, title: "Sales Gross Contribution", type: .salesGrossContribution)]
default:
assertionFailure("Only Purchase and sales are handle here")
}
}
But I am not able to declare array
var itemList = [HomeSubItemType]()
//ERROR HERE
Protocol 'HomeSubItemType' can only be used as a generic constraint because it has Self or associated type requirements
Please help me to fix this. Thanks in advance
Upvotes: 3
Views: 5242
Reputation: 52053
Update
This is a completely different solution, focused on solving the problem rather than using generics
First I created a protocol for the enums, it's empty since it is just meant group them together
protocol RowType {}
both enums implements this, not shown here, and I modified ListRowType to
protocol ListRowType {
var title: String {get}
var image: UIImage {get}
var type: RowType {get}
}
and skipped HomeSubItemType
completely.
SubItem
is now
struct SubItem: ListRowType {
var type: RowType
var title: String
var image: UIImage
}
and my test code
var itemList = [ListRowType]()
let sale = SubItem(type: SalesRowType.salesInvoicing, title: "XYZ", image: UIImage())
itemList.append(sale)
let purchase = SubItem(type: PurchaseRowType.purchaseOrders, title: "ABC", image: UIImage())
itemList.append(purchase)
This can of course be used with the original PurchaseSubItem
and SalesSubItem
instead of SubItem
if that is preferred
I replaced the two structs with a generic struct
struct SubItem<T>: HomeSubItemType {
typealias RowType = T
var type: T
var title: String
var image: UIImage
}
and used it like this
var itemList = [SubItem<SalesRowType>]()
var item = SubItem(type: SalesRowType.salesInvoicing, title: "XYZ", image: UIImage())
itemList.append(item)
So you need to arrays which is probably best anyway, if you for some reason must have only one then declare it
var itemList = [Any]()
Upvotes: 2