[英]Using a Swift enum as view tag numbers without rawValue
我有一個整數枚舉,我想將其用於viewWithTag(_:)
編號,但它給了我錯誤“無法將類型 'viewTags' 的值轉換為預期的參數類型 'Int'”,即使兩個枚舉viewWithTag(_:)
需要的標簽號是一個Int
。
這非常簡單,如果我使用rawValue
屬性,我可以讓它工作,但這比我想要的更混亂和麻煩。
enum viewTags: Int {
case rotateMirroredBtn
case iPhone6SP_7P_8P
case iPhoneX_Xs
case iPhoneXs_Max
case iPhone_Xr
case unknown
}
// error on if statement "Cannot convert value of type 'viewTags' to expected argument type 'Int'"
if let tmpButton = self.view.viewWithTag(viewTags.rotateMirroredBtn) as? UIButton {
tmpButton.removeFromSuperview()
}
您可以輕松地在UIView
上添加一個擴展來為您進行轉換。 您只需要使用泛型參數將參數限制為可以從中獲取Int
的內容。
extension UIView
{
/**
Returns the view’s nearest descendant (including itself) whose `tag`
matches the raw value of the given value, or `nil` if no subview
has that tag.
- parameter tag: A value that can be converted to an `Int`.
*/
func firstView <Tag : RawRepresentable> (taggedBy tag: Tag) -> UIView?
where Tag.RawValue == Int
{
let intValue = tag.rawValue
return self.viewWithTag(intValue)
}
}
約束T : RawRepresentable where T.RawValue == Int
可以由您的Int
支持的枚舉來實現。
非通用表單也很簡單: func firstView(taggedBy viewTag: ViewTag) -> UIView?
另外,您還可以添加一個方法來將“組合”值的原始值應用到視圖的:
func applyTag <Tag : RawRepresentable> (_ tag: Tag)
where Tag.RawValue == Int
{
self.tag = tag.rawValue
}
(不幸的是,沒有辦法將其寫為屬性,例如var composedTag: Tag where Tag : RawRepresentable, Tag.RawValue == Int
因為計算屬性不能像方法一樣創建自己的通用上下文。)
我和原來的海報一樣,不喜歡在代碼中使用案例的rawValue
,所以我在我的枚舉中添加了計算類型屬性。 我使用的是 Xcode v11.3.1 和 Swift v5.1.3。
例如,我編寫的許多單元測試都使用“魔法”值來為表視圖創建 IndexPath,代碼如下:
let activeIndexPath = IndexPath(row: 0, section: 0)
let finishedIndexPath = IndexPath(row: 0, section: 1)
我不想這樣做,即使它是對“魔法”值的改進:
let activeIndexPath = IndexPath(row: 0, section: TableViewSection.active.rawValue)
let finishedIndexPath = IndexPath(row: 0, section: TableViewSection.finished.rawValue)
我最關心的是我正在測試的表視圖部分,所以我想出了這個枚舉,它使用計算類型屬性來獲取 Int rawValues:
enum TableViewSection: Int {
case active
case finished
static var sectionActive: Int { return Self.active.rawValue }
static var sectionFinished: Int { return Self.finished.rawValue }
}
現在我可以像這樣創建一個 IndexPath:
let indexPathActive = IndexPath(row: 0, section: TableViewSection.sectionActive)
缺點是您需要為每種情況使用具有相似名稱的計算屬性,但最終結果在調用站點上更具描述性(盡管我猜使用 rawValue 的代碼也是描述性的),現在我不必記住表視圖的每個特定部分使用哪個 Int 值,我不必再使用“魔術”值,我們都知道這是一件壞事。
希望有幫助!
您唯一缺少的是rawValue
。 只需將viewTags.rotateMirroredBtn
替換為viewTags.rotateMirroredBtn
viewTags.rotateMirroredBtn.rawValue
如下所示:
if let tmpButton = self.view.viewWithTag(viewTags.rotateMirroredBtn.rawValue) as? UIButton {
tmpButton.removeFromSuperview()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.