试图给 UIButton 一个特殊的属性
Posted
技术标签:
【中文标题】试图给 UIButton 一个特殊的属性【英文标题】:Trying to give UIButton a special property 【发布时间】:2020-01-31 17:50:31 【问题描述】:我需要 UIButton 来拥有 bookId 属性。我尝试了以下代码,但它给了我错误Property 'self.bookId' not initialized at super.init call
。当单击按钮时,我需要该属性能够在数据库中查询该特定 bookId。
import UIKit
class BookUIButton: UIButton
var bookId: String
init(frame: CGRect, bookId: String)
super.init(frame: frame);
self.bookId = bookId
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
override init(frame: CGRect)
super.init(frame: frame)
override func awakeFromNib()
super.awakeFromNib()
//TODO: Code for our button
任何帮助将不胜感激!!!
【问题讨论】:
去掉init(frame:)
的实现,在init(coder:)
中给bookId
一个默认值。通常,该错误告诉您必须在您拥有的每个初始化程序中初始化您的属性。
我相信这在另一篇 *** 文章中得到了回答:Here
【参考方案1】:
swift 强制您在每个成员 var 曾经/可能被使用之前对其进行初始化。由于无法确定在超级转弯时会发生什么,因此它会出错:比抱歉更安全!
解决方案一:
class BookUIButton: UIButton
var bookId: String?
init(frame: CGRect, bookId: String)
super.init(frame: frame);
self.bookId = bookId
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
override init(frame: CGRect)
super.init(frame: frame)
override func awakeFromNib()
super.awakeFromNib()
//TODO: Code for our button
解决方案 2: 有一种更好的方法可以跳过此错误。所以你所要做的就是在声明后初始化成员:
class BookUIButton: UIButton
var bookId: String = String()
init(frame: CGRect, bookId: String)
super.init(frame: frame);
self.bookId = bookId
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
override init(frame: CGRect)
super.init(frame: frame)
override func awakeFromNib()
super.awakeFromNib()
//TODO: Code for our button
【讨论】:
将它放在 init 中的目的是避免可选。 @bsod 检查解决方案 2 现在它只是空的,仍然不能保证用户有一个值。 swift 强制您在每个成员 var 曾经/可能被使用之前对其进行初始化。由于无法确定超级转弯时会发生什么,因此会出错:比抱歉更安全 如果在调用 super 之前初始化字符串,则可以使用可选字符串或空字符串。【参考方案2】:将其命名为 bookId 重要吗?成为一个字符串很重要吗?
如果你只是给 UIButton 一个标签呢? (例如ButtonName.tag = Int
)
【讨论】:
【参考方案3】:由于您始终可以从情节提要中实例化一个按钮,因此该按钮需要有一个必需的 init?(coder aDecoder: NSCoder)。仅当您在情节提要中插入按钮时才需要该方法。 如果按钮实际上是通过情节提要创建的,那么它当然不会很快(在初始化时)拥有 id,因此它不是可选的。
由于我假设您将始终以编程方式而不是通过情节提要来实例化按钮,因此您可以使用您的参数实现自己的 init,然后在所需的 init 中插入一个 fatalError。
这将编译为 fatalError 返回 Never(意味着它永远不会返回),因此编译器可以理解 bookId 实际上永远不会为 nil。
实际上,如果您删除所需的 init,Xcode 会建议您插入带有 fatalError 的方法,并且如果您愿意,它会自动为您完成。
当然,在那之后,如果你把这个类的一个按钮放在storyboard中,它会崩溃,所以不要那样做。
如果您不打算为该按钮(或查看)。
PS:在简要介绍了如何做你想做的事情之后,我想建议你不要在这种情况下这样做,因为按钮保存关于你的某些 API 的任何类型的数据似乎是个坏主意需要打电话。该按钮应该只是一个按钮,并在用户点击它时通知您。然后,当按下按钮时,其他一些类应该处理要做什么,使用其他一些模型来获取该按钮点击对应的 bookId。
完全不同的是,如果您要添加一些属性来帮助按钮看起来不同,或者添加一些特定于按钮使用的其他行为(这只是可点击的并通知点击)
【讨论】:
以上是关于试图给 UIButton 一个特殊的属性的主要内容,如果未能解决你的问题,请参考以下文章
如何滚动到 UIScrollview 中的 UIButton 位置
如何在 UIToolbar 完成按钮中将焦点从一个 UIButton 设置到另一个 UIButton