情节提要中设置的 @IBInspectable 的值未传播到代码
Value of @IBInspectable set in storyboard not propagated to the code
没有任何使用 iOS 的经验,我被要求升级到 Swift 4 一个使用 Swift 的应用程序 3. 我更新了在 [=56 中使用的语言=] 并且我遵循了 xCode 提出的建议(明确使用 @objc
)。
修复所有错误后,应用程序可以正常工作,但一项 UI 相关功能不再有效。该应用程序有一个自定义 UITextField
用于输入密码。根据自定义文本字段的 @IBInspectable
class 字段的值,文本是否隐藏。
此变量的值已在 MainStoryboard 中正确设置,但是当实例化 class 时,此值未设置为情节提要中的值,因此,自定义文本字段的行为不正确这应该。日志没有提到任何错误。
有人遇到同样的问题吗?
我检查了 storyboard 和 class,我没有发现任何问题,我还比较了版本的代码 Swift 3 和我更新的 Swift 4 和没有区别(@objc
除外)。
是否还有其他内容可以帮助我找到为什么 MainStoryboard 中设置的值未传播到 class?
编辑
下面是问题涉及的代码:
- 声明了一个变量
isPassword
来反映IBInspectable变量的值
- 声明变量
IBInspectable
当 awakeFromNib
取决于 isPassword
的值时,调用隐藏或不隐藏文本的方法
@IBDesignable class CustomEditText: UITextField {
var isPassword = false
// Inspector variable determining if the text must be hidden or not
@IBInspectable var isAPasswordField: Bool {
get{
return self.isPassword
}
set{
self.isPassword = isAPasswordField
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
setup() // Set borders, font, ...
}
override func awakeFromNib() {
super.awakeFromNib()
if isPassword { // isPassword does not reflect the value of isAPasswordField set in storyboard
self.isSecureTextEntry = true
setRevealButton() // the text is hidden
} else {
setCustomClearButton() // the text is not hidden
}
}
...
回答
@Alladinian 给出了很好的答案。
为了完整起见,下面是我找到的另一个解决方案:
@IBInspectable var isPasswordField: Bool = false {
didSet{
self.isPassword = isPasswordField
if isPassword {
self.isSecureTextEntry = true
setRevealButton()
} else {
setCustomClearButton()
}
}
}
正确的形式是(注意 setter 赋值):
@IBInspectable var isAPasswordField: Bool {
get {
return self.isPassword
}
set {
self.isPassword = newValue
}
}
因为实际值尚未(并且不会 - 至少 'directly')在 isAPasswordField
上设置(请记住,我们正在实施setter 计算 属性 毕竟......)
此外,您为什么不直接使用 isPassword
,将其标记为可检查,避免需要额外的 ivar?
PS:newValue
为待设置值的默认名称。您可以在 Swift 编程语言书籍
的 Shorthand Setter Declaration 部分阅读更多相关信息
以下代码适用于较新的版本:
@IBInspectable var isAPass: Bool {
get {
return self.isSecureTextEntry
}
set {
self.isSecureTextEntry = newValue
}
}
没有任何使用 iOS 的经验,我被要求升级到 Swift 4 一个使用 Swift 的应用程序 3. 我更新了在 [=56 中使用的语言=] 并且我遵循了 xCode 提出的建议(明确使用 @objc
)。
修复所有错误后,应用程序可以正常工作,但一项 UI 相关功能不再有效。该应用程序有一个自定义 UITextField
用于输入密码。根据自定义文本字段的 @IBInspectable
class 字段的值,文本是否隐藏。
此变量的值已在 MainStoryboard 中正确设置,但是当实例化 class 时,此值未设置为情节提要中的值,因此,自定义文本字段的行为不正确这应该。日志没有提到任何错误。
有人遇到同样的问题吗?
我检查了 storyboard 和 class,我没有发现任何问题,我还比较了版本的代码 Swift 3 和我更新的 Swift 4 和没有区别(@objc
除外)。
是否还有其他内容可以帮助我找到为什么 MainStoryboard 中设置的值未传播到 class?
编辑
下面是问题涉及的代码:
- 声明了一个变量
isPassword
来反映IBInspectable变量的值 - 声明变量
IBInspectable
当
awakeFromNib
取决于isPassword
的值时,调用隐藏或不隐藏文本的方法@IBDesignable class CustomEditText: UITextField { var isPassword = false // Inspector variable determining if the text must be hidden or not @IBInspectable var isAPasswordField: Bool { get{ return self.isPassword } set{ self.isPassword = isAPasswordField } } override init(frame: CGRect) { super.init(frame: frame) setup() } required init(coder aDecoder: NSCoder) { super.init(coder: aDecoder)! setup() // Set borders, font, ... } override func awakeFromNib() { super.awakeFromNib() if isPassword { // isPassword does not reflect the value of isAPasswordField set in storyboard self.isSecureTextEntry = true setRevealButton() // the text is hidden } else { setCustomClearButton() // the text is not hidden } }
...
回答
@Alladinian 给出了很好的答案。 为了完整起见,下面是我找到的另一个解决方案:
@IBInspectable var isPasswordField: Bool = false {
didSet{
self.isPassword = isPasswordField
if isPassword {
self.isSecureTextEntry = true
setRevealButton()
} else {
setCustomClearButton()
}
}
}
正确的形式是(注意 setter 赋值):
@IBInspectable var isAPasswordField: Bool {
get {
return self.isPassword
}
set {
self.isPassword = newValue
}
}
因为实际值尚未(并且不会 - 至少 'directly')在 isAPasswordField
上设置(请记住,我们正在实施setter 计算 属性 毕竟......)
此外,您为什么不直接使用 isPassword
,将其标记为可检查,避免需要额外的 ivar?
PS:newValue
为待设置值的默认名称。您可以在 Swift 编程语言书籍
以下代码适用于较新的版本:
@IBInspectable var isAPass: Bool {
get {
return self.isSecureTextEntry
}
set {
self.isSecureTextEntry = newValue
}
}