我试图了解如何正确子类视图,该视图是从 Swift 中的 xib 加载的。
我有TitleDetailLabel
类,它是UIControl
的子类。此类具有titleLabel
和detailLabel
UILabel
的插座。
class TitleDetailLabel: UIControl {
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var detailLabel: UILabel!
override func awakeAfterUsingCoder(aDecoder: NSCoder) -> AnyObject? {
return NTHAwakeAfterUsingCoder(aDecoder, nibName: "TitleDetailLabel")
}
func setTitle(text: String) {
self.titleLabel.text = text
}
func setDetailText(text: String) {
self.detailLabel.text = text
}
}
XIB结构:
- 占位符
- 文件所有者:
NSObject
(未更改) - 第一响应者
- 文件所有者:
- 标题详细信息标签 -
UIView
-TitleDetailLabel
类- 标签 -
UILabel
- 标题标签 - 标签 -
UILabel
- 详细标签
- 标签 -
在故事板中,我有视图控制器和占位符 - 带有约束的简单UIView
对象。
我已经为类创建了扩展UIView
以简化与我感兴趣的对象的交换占位符。它适用于这个TitleDetailLabel
类。下面是它的外观:
extension UIView {
public func NTHAwakeAfterUsingCoder(aDecoder: NSCoder, nibName: String) -> AnyObject? {
if (self.subviews.count == 0) {
let nib = UINib(nibName: nibName, bundle: nil)
let loadedView = nib.instantiateWithOwner(nil, options: nil).first as UIView
/// set view as placeholder is set
loadedView.frame = self.frame
loadedView.autoresizingMask = self.autoresizingMask
loadedView.setTranslatesAutoresizingMaskIntoConstraints(self.translatesAutoresizingMaskIntoConstraints())
for constraint in self.constraints() as [NSLayoutConstraint] {
var firstItem = constraint.firstItem as UIView
if firstItem == self {
firstItem = loadedView
}
var secondItem = constraint.secondItem as UIView?
if secondItem != nil {
if secondItem! == self {
secondItem = loadedView
}
}
loadedView.addConstraint(NSLayoutConstraint(item: firstItem, attribute: constraint.firstAttribute, relatedBy: constraint.relation, toItem: secondItem, attribute: constraint.secondAttribute, multiplier: constraint.multiplier, constant: constraint.constant))
}
return loadedView
}
return self
}
}
我决定创建BasicTitleDetailLabel
类的子类TitleDetailLabel
以保留一些配置代码和其他东西。
class BasicTitleDetailLabel: TitleDetailLabel {
override func awakeFromNib() {
super.awakeFromNib()
self.setup()
}
override init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setup()
}
private func setup() {
self.titleLabel.textColor = UIColor.NTHCadetGrayColor()
self.detailLabel.textColor = UIColor.NTHLinkWaterColor()
}
}
但是每次我将此占位符的类从 TitleDetailLabel
更改为 BasicTitleDetailLabel
后,应用程序都会崩溃。
应用程序崩溃,因为titleLabel
和detailLabel
为零。
我怎样才能在 xib 中正确使用这个TitleDetailLabel
类以及如何正确地对其进行子类化?我不想创建另一个看起来与第一个使用子类相同的 xib。
提前谢谢。
.xib 文件的文件所有者设置为.swift文件。还要为根视图添加一个出口,然后从代码加载 xib。这就是我为类似项目所做的:
import UIKit
class ResuableCustomView: UIView {
@IBOutlet var view: UIView!
@IBOutlet weak var label: UILabel!
@IBAction func buttonTap(sender: UIButton) {
label.text = "Hi"
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
NSBundle.mainBundle().loadNibNamed("ReusableCustomView", owner: self, options: nil)[0] as! UIView
self.addSubview(view)
view.frame = self.bounds
}
}
它与您的方法略有不同,但您可以添加init:frame
方法。如果您有 awakeFromNib
方法,则不要在 awakeFromNib
和 init:coder
中加载 setup
方法。
我对上述代码项目的完整答案在这里或观看此视频。