如何使 IndexPath rawRepresentable?
How to make IndexPath rawRepresentable?
我正在尝试重构代码并创建一个枚举 class 来保存 table 视图单元格的索引路径。
我想让代码这样工作:
enum TableViewCell: IndexPath {
case shopImageView = [0,0]
case selectShopImageButton = [0,1]
}
但是编译器说 indexPath 不是 rawRepresentable:
'TableViewCell' declares raw type 'IndexPath', but does not conform to RawRepresentable and conformance could not be synthesized
Raw value for enum case must be a literal
如何使 indexPath rawRepresentable?目前的代码是这样的,我想改进它。
enum TableViewCell {
case shopImageView
case selectShopImageButton
case shopNameLocal
case shopNameEN
case addressLocal
case addressEN
case selectAddressButton
case openingHours
case datePickers
case phone
case email
case uploadShopFormButton
var indexPath: IndexPath {
switch self {
case .shopImageView: return [0,0]
case .selectShopImageButton: return [0,1]
case .shopNameLocal: return [0,2]
case .shopNameEN: return [0,3]
case .addressLocal: return [0,4]
case .addressEN: return [0,5]
case .selectAddressButton: return [0,6]
case .openingHours: return [0,7]
case .datePickers: return [0,8]
case .phone: return [0,9]
case .email: return [0,10]
case .uploadShopFormButton: return [0,11]
}
}
}
还有其他方法,但不一定更好,反正你可以把代码缩减成这样。
enum TableViewCell: Int {
case shopImageView = 0
case selectShopImageButton = 1
case shopNameLocal = 2
case shopNameEN = 3
case addressLocal
case addressEN
case selectAddressButton
case openingHours
case datePickers
case phone
case email
case uploadShopFormButton
var indexPath: IndexPath {
return [0, self.rawValue]
}
}
另外请记住,这也取决于您如何使用它们,例如您在何处以及如何传递参数。
方法之一.
extension IndexPath {
init(using type: TableViewCell) {
self.init(row: type.rawValue, section: 0)
}
}
let indexPath = IndexPath(using: .shopNameEN)
另一种使用硬编码 TableView
IndexPath
的方法是使用具有静态属性的 enum
。这样做的好处是,如果您在各种 TableView
委托方法中引用 IndexPath
,并且您需要更改 IndexPath
引用,那么您只需在枚举。
private enum TableIndex {
// Section 0: Information
static let information = IndexPath(row: 0, section: 0)
// Section 1: Preferences
static let notifications = IndexPath(row: 0, section: 1)
static let units = IndexPath(row: 1, section: 1)
static let hapticFeedback = IndexPath(row: 2, section: 1)
// Section 2: Links
static let leaveReview = IndexPath(row: 0, section: 2)
static let support = IndexPath(row: 1, section: 2)
static let privacyPolicy = IndexPath(row: 2, section: 2)
static let disclaimer = IndexPath(row: 3, section: 2)
}
然后您可以像这样引用它们:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath {
case TableIndex.information:
// do something
case TableIndex.notifications:
// do something
case TableIndex.units:
// do something
// etc
default:
break
}
}
extension IndexPath : RawRepresentable {
public init?(rawValue: (Int, Int)) {
self.init(row: rawValue.0, section: rawValue.1)
}
public var rawValue: (Int, Int) {
(self.row, self.section)
}
}
// We can't use array literal for raw value of an enum, but we can use `String` literal instead.
extension IndexPath: ExpressibleByStringLiteral {
public init(stringLiteral: StringLiteralType) {
let a = stringLiteral.split(separator: ",")
if let row = Int(a[0]), let section = Int(a[1]) {
self.init(row: row, section: section)
} else {
self.init(row: 0, section: 0)
}
}
}
// We can use array literals to initialize `IndexPath` but not to define an enum case.
enum TableViewCell: IndexPath {
case shopImageView = "0,0" // `String` literal
case selectShopImageButton = "0,1" // `String` literal
}
print(TableViewCell.selectShopImageButton.rawValue)
我正在尝试重构代码并创建一个枚举 class 来保存 table 视图单元格的索引路径。
我想让代码这样工作:
enum TableViewCell: IndexPath {
case shopImageView = [0,0]
case selectShopImageButton = [0,1]
}
但是编译器说 indexPath 不是 rawRepresentable:
'TableViewCell' declares raw type 'IndexPath', but does not conform to RawRepresentable and conformance could not be synthesized
Raw value for enum case must be a literal
如何使 indexPath rawRepresentable?目前的代码是这样的,我想改进它。
enum TableViewCell {
case shopImageView
case selectShopImageButton
case shopNameLocal
case shopNameEN
case addressLocal
case addressEN
case selectAddressButton
case openingHours
case datePickers
case phone
case email
case uploadShopFormButton
var indexPath: IndexPath {
switch self {
case .shopImageView: return [0,0]
case .selectShopImageButton: return [0,1]
case .shopNameLocal: return [0,2]
case .shopNameEN: return [0,3]
case .addressLocal: return [0,4]
case .addressEN: return [0,5]
case .selectAddressButton: return [0,6]
case .openingHours: return [0,7]
case .datePickers: return [0,8]
case .phone: return [0,9]
case .email: return [0,10]
case .uploadShopFormButton: return [0,11]
}
}
}
还有其他方法,但不一定更好,反正你可以把代码缩减成这样。
enum TableViewCell: Int {
case shopImageView = 0
case selectShopImageButton = 1
case shopNameLocal = 2
case shopNameEN = 3
case addressLocal
case addressEN
case selectAddressButton
case openingHours
case datePickers
case phone
case email
case uploadShopFormButton
var indexPath: IndexPath {
return [0, self.rawValue]
}
}
另外请记住,这也取决于您如何使用它们,例如您在何处以及如何传递参数。
方法之一.
extension IndexPath {
init(using type: TableViewCell) {
self.init(row: type.rawValue, section: 0)
}
}
let indexPath = IndexPath(using: .shopNameEN)
另一种使用硬编码 TableView
IndexPath
的方法是使用具有静态属性的 enum
。这样做的好处是,如果您在各种 TableView
委托方法中引用 IndexPath
,并且您需要更改 IndexPath
引用,那么您只需在枚举。
private enum TableIndex {
// Section 0: Information
static let information = IndexPath(row: 0, section: 0)
// Section 1: Preferences
static let notifications = IndexPath(row: 0, section: 1)
static let units = IndexPath(row: 1, section: 1)
static let hapticFeedback = IndexPath(row: 2, section: 1)
// Section 2: Links
static let leaveReview = IndexPath(row: 0, section: 2)
static let support = IndexPath(row: 1, section: 2)
static let privacyPolicy = IndexPath(row: 2, section: 2)
static let disclaimer = IndexPath(row: 3, section: 2)
}
然后您可以像这样引用它们:
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch indexPath {
case TableIndex.information:
// do something
case TableIndex.notifications:
// do something
case TableIndex.units:
// do something
// etc
default:
break
}
}
extension IndexPath : RawRepresentable {
public init?(rawValue: (Int, Int)) {
self.init(row: rawValue.0, section: rawValue.1)
}
public var rawValue: (Int, Int) {
(self.row, self.section)
}
}
// We can't use array literal for raw value of an enum, but we can use `String` literal instead.
extension IndexPath: ExpressibleByStringLiteral {
public init(stringLiteral: StringLiteralType) {
let a = stringLiteral.split(separator: ",")
if let row = Int(a[0]), let section = Int(a[1]) {
self.init(row: row, section: section)
} else {
self.init(row: 0, section: 0)
}
}
}
// We can use array literals to initialize `IndexPath` but not to define an enum case.
enum TableViewCell: IndexPath {
case shopImageView = "0,0" // `String` literal
case selectShopImageButton = "0,1" // `String` literal
}
print(TableViewCell.selectShopImageButton.rawValue)