我有一个整数枚举数,我想将其用于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()
}
答案 0 :(得分:2)
您可以轻松地在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
,因为计算出的属性无法像方法那样创建自己的通用上下文。)
答案 1 :(得分:1)
我和原始张贴者一样,不喜欢在代码中使用案例的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值,而且我也不必再使用“魔术”值了,我们都知道这是一件坏事。
希望有帮助!
答案 2 :(得分:0)
您唯一缺少的是rawValue
。像这样用viewTags.rotateMirroredBtn
替换viewTags.rotateMirroredBtn.rawValue
:
if let tmpButton = self.view.viewWithTag(viewTags.rotateMirroredBtn.rawValue) as? UIButton {
tmpButton.removeFromSuperview()
}