Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/104.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 从超类UIView连接的IBoutlet仍然为零_Ios_Swift_Xcode_Iboutlet - Fatal编程技术网

Ios 从超类UIView连接的IBoutlet仍然为零

Ios 从超类UIView连接的IBoutlet仍然为零,ios,swift,xcode,iboutlet,Ios,Swift,Xcode,Iboutlet,我用笔尖工作。我有两个屏幕将使用具有相同行为的“相同”UIView组件。它不是同一个组件,因为在每个屏幕中我都放置了一个UIView,并进行了相同的配置,如图所示 为了解决这个问题并防止在其他类中复制相同的代码,我编写了一个类,即UIView子类,包含我需要的所有函数 之后,我将自定义类作为这些UIView组件的超类,以继承IBOutlets和所有函数 我的自定义类没有在Nib中定义,只是.swift类 我进行了所有必要的连接,但在运行时,IBOutlets是Nil 我的自定义类的代

我用笔尖工作。我有两个屏幕将使用具有相同行为的“相同”
UIView
组件。它不是同一个组件,因为在每个屏幕中我都放置了一个
UIView
,并进行了相同的配置,如图所示

为了解决这个问题并防止在其他类中复制相同的代码,我编写了一个类,即
UIView
子类,包含我需要的所有函数

之后,我将自定义类作为这些
UIView
组件的超类,以继承
IBOutlets
和所有函数

我的自定义类没有在
Nib
中定义,只是
.swift

我进行了所有必要的连接,但在运行时,
IBOutlets
Nil

我的自定义类的代码:

class FeelingGuideView: UIView {

    @IBOutlet weak var firstScreen: UILabel!
    @IBOutlet weak var secondScreen: UILabel!
    @IBOutlet weak var thirdScreen: UILabel!
    @IBOutlet weak var fourthScreen: UILabel!

    private var labelsToManage: [UILabel] = []
    private var willShow: Int!
    private var didShow: Int!

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.initLabelManagement()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)

        self.initLabelManagement()
    }

    private func initLabelManagement() {
        self.initLabelVector()
        self.willShow = 0
        self.didShow = 0
        self.setupLabelToShow(label: labelsToManage[0])
        self.setupLabels()
    }

    private func initLabelVector() {
        self.labelsToManage.append(self.firstScreen)
        self.labelsToManage.append(self.secondScreen)
        self.labelsToManage.append(self.thirdScreen)
        self.labelsToManage.append(self.fourthScreen)
    }

    private func setupLabels() {

        for label in labelsToManage {
            label.layer.borderWidth = 2.0
            label.layer.borderColor = UIColor(hex: "1A8BFB").cgColor
        }
    }

    func willShowFeelCell(at index: Int) {
        self.willShow = index

        if willShow > didShow {
            self.setupLabelToShow(label: labelsToManage[willShow])
        }
        else if willShow < didShow {

            for i in didShow ... willShow + 1 {

                let label = labelsToManage[i]
                self.setupLabelToHide(label: label)
            }
        }
    }

    private func setupLabelToShow(label: UILabel) {
        label.textColor = UIColor.white
        label.backgroundColor = UIColor(hex: "1A8BFB")
    }

    private func setupLabelToHide(label: UILabel) {
        label.textColor = UIColor(hex: "1A8BFB")
        label.backgroundColor = UIColor.white
    }
}
当调用自定义类中的
init()
时,
IBOutlets
尚未连接

因此,我在父视图上创建了一个引用,并从
viewdiload()
方法调用
iniLabelManagement()


谢谢马特的帮助和耐心

问题在于以下代码:

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
    self.initLabelManagement()
}
问题是
init(coder:)
现在谈论视图的出口还为时过早,这正是
initLabelManagement
所做的;插座还没有接通。换言之:

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}
override func awakeFromNib() {
    super.awakeFromNib()
    self.initLabelManagement()
}

我是如何得出这个答案的: 作为测试,我尝试了以下方法:

class MyView : UIView {
    @IBOutlet var mySubview : UIView!
    required init?(coder aDecoder: NSCoder) {
        super.init(coder:aDecoder)
        print(#function, self.mySubview)
    }
    override func awakeFromNib() {
        super.awakeFromNib()
        print(#function, self.mySubview)
    }
}
以下是输出:

init(coder:) nil
awakeFromNib() <UIView: 0x7fc17ef05b70 ... >
init(编码器:)nil
awakeFromNib()
这证明了什么:

  • init(编码器:)
    太快了;插座还没有接通

  • awakeFromNib
    不是很快;插座已经连接好了

  • awakeFromNib
    被调用,尽管您声称相反


也许
init(coder:)
太早了:视图存在,但其出口尚未连接。在稍后的初始化时刻,例如覆盖
willMove(toWindow:)
didMoveToWindow
之前,尝试不访问视图出口。另外,我认为您声称的
awakeFromNib
没有被称为非常令人不安,因为那是我本应该尝试的初始化时刻。非常感谢!这正是问题所在。在init中,插座尚未连接。我在
viewDidLoad()
中调用了父类上的
initLabelManagement()
func并工作。非常感谢。很好,但是您现在违反了视图类的封装。最好弄清楚视图本身何时可以保证其插座连接。这正是我所想的
awakeFromNib
。谢谢,我会试试的。当我这样做时,我会将答案可视化。我添加了一个答案,证明应该调用
awakeFromNib
,现在是开始讨论视图的出口的正确时机。
setupLabels()
(来自
initLabelManagement()
的消息)也适用于该层,在
awakeFromNib()
中,哪一帧可能还没有计算出来。这不是应该在
layoutSubviews()
或类似的东西上完成的吗?@AlejandroIván我关心的不是这个。OP询问在
init(coder:)
中谈到outlet属性时,为什么在展开可选文件时出现“
nil
错误,我回答了这个问题。这里所采取的整个方法的可取性不在本讨论的范围之内。
init(coder:) nil
awakeFromNib() <UIView: 0x7fc17ef05b70 ... >