【发布时间】:2015-11-27 07:29:07
【问题描述】:
我正在使用 Swift 和 Xcode 6.4 来获得它的价值。
所以我有一个视图控制器,它将包含一些多对 UILabel 和 UIImageViews。我想将 UILabel-UIImageView 对放入自定义 UIView 中,因此我可以简单地在上述视图控制器中重复使用相同的结构。 (我知道这可以翻译成 UITableView,但为了~学习~请多多包涵)。事实证明,这比我想象的要复杂得多,我很难找出“正确”的方法来让这一切在 IB 中发挥作用。
目前我一直在纠结于 UIView 子类和相应的 XIB,覆盖 init(frame:) 和 init(coder),从 nib 加载视图并将其添加为子视图。到目前为止,这是我在互联网上看到/阅读的内容。 (大概是这样:http://iphonedev.tv/blog/2014/12/15/create-an-ibdesignable-uiview-subclass-with-code-from-an-xib-file-in-xcode-6)。
这给了我一个导致 init(coder) 和从包中加载 nib 之间无限循环的问题。奇怪的是,这些文章或以前关于堆栈溢出的答案都没有提到这一点!
好的,所以我检查了 init(coder) 以查看是否已经添加了子视图。这似乎“解决了”这个问题。但是,当我尝试为它们分配值时,我开始遇到我的自定义视图出口为零的问题。
我做了一个 didSet 并添加了一个断点来查看...它们肯定是在某个点设置的,但是当我尝试修改标签的 textColor 时,该标签为 nil。 我有点扯我的头发在这里。
可重用组件看起来像是软件设计 101,但我觉得 Apple 正在密谋反对我。我应该在这里使用容器 VC 吗?我应该只是嵌套视图并在我的主要 VC 中拥有大量愚蠢的渠道吗?为什么这么复杂?为什么每个人的例子都不适合我?
想要的结果(假装整个是VC,盒子是我想要的自定义uiviews):
感谢阅读。
以下是我的自定义 UIView 子类。在我的主情节提要中,我将 UIViews 的子类设置为它们的类。
class StageCardView: UIView {
@IBOutlet weak private var stageLabel: UILabel! {
didSet {
NSLog("I will murder you %@", stageLabel)
}
}
@IBOutlet weak private var stageImage: UIImageView!
var stageName : String? {
didSet {
self.stageLabel.text = stageName
}
}
var imageName : String? {
didSet {
self.stageImage.image = UIImage(named: imageName!)
}
}
var textColor : UIColor? {
didSet {
self.stageLabel.textColor = textColor
}
}
var splatColor : UIColor? {
didSet {
let splatImage = UIImage(named: "backsplat")?.tintedImageWithColor(splatColor!)
self.backgroundColor = UIColor(patternImage: splatImage!)
}
}
// MARK: init
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
if self.subviews.count == 0 {
setup()
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
func setup() {
if let view = NSBundle.mainBundle().loadNibNamed("StageCardView", owner: self, options: nil).first as? StageCardView {
view.frame = bounds
view.autoresizingMask = UIViewAutoresizing.FlexibleWidth | UIViewAutoresizing.FlexibleHeight
addSubview(view)
}
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func drawRect(rect: CGRect) {
// Drawing code
}
*/
}
编辑:这是我目前所能得到的......
XIB:
结果:
问题:当尝试访问标签或图像出口时,它们是 nil。在所述访问的断点处检查时,标签和图像子视图都在那里,并且视图层次结构符合预期。
如果需要的话,我可以在代码中完成这一切,但我并不热衷于在代码中执行 Autolayout,所以如果有办法避免它,我宁愿不这样做!
编辑/问题转换:
我想出了如何让 outlet 不再为零。
来自这个 SO 答案的灵感:Loaded nib but the view outlet was not set - new to InterfaceBuilder 除了分配视图出口之外,我分配了各个组件出口。
现在,我只是在墙上扔屎,看看它是否会粘住。有谁知道我为什么要这样做?这是什么黑魔法?
【问题讨论】:
-
你找到解决办法了吗?
标签: ios swift uiview interface-builder xib