簡體   English   中英

使用 Swift 枚舉作為沒有 rawValue 的視圖標簽號

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM